Skip to content

Commit 7e2dd3a

Browse files
committed
fix: avoid YouTube error 153 video player configuration error
1 parent 4ace959 commit 7e2dd3a

File tree

4 files changed

+50
-36
lines changed

4 files changed

+50
-36
lines changed

internal/reader/rewrite/content_rewrite_functions.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,9 @@ func getYoutubVideoIDFromURL(entryURL string) string {
286286
}
287287

288288
func buildVideoPlayerIframe(absoluteVideoURL string) string {
289-
return `<iframe width="650" height="350" frameborder="0" src="` + absoluteVideoURL + `" allowfullscreen></iframe>`
289+
// Note: the referrerpolicy seems to be required to avoid YouTube error 153 video player configuration error
290+
// See https://developers.google.com/youtube/terms/required-minimum-functionality#embedded-player-api-client-identity
291+
return `<iframe width="650" height="350" frameborder="0" src="` + absoluteVideoURL + `" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe>`
290292
}
291293

292294
func addVideoPlayerIframe(absoluteVideoURL, entryContent string) string {

internal/reader/rewrite/content_rewrite_test.go

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func TestRewriteYoutubeVideoLink(t *testing.T) {
7272
controlEntry := &model.Entry{
7373
URL: "https://www.youtube.com/watch?v=1234",
7474
Title: `A title`,
75-
Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1234" allowfullscreen></iframe><br>Video Description`,
75+
Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1234" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
7676
}
7777
testEntry := &model.Entry{
7878
URL: "https://www.youtube.com/watch?v=1234",
@@ -92,7 +92,7 @@ func TestRewriteYoutubeShortLink(t *testing.T) {
9292
controlEntry := &model.Entry{
9393
URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
9494
Title: `A title`,
95-
Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1LUWKWZkPjo" allowfullscreen></iframe><br>Video Description`,
95+
Content: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/1LUWKWZkPjo" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
9696
}
9797
testEntry := &model.Entry{
9898
URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
@@ -140,7 +140,7 @@ func TestRewriteYoutubeLinkAndCustomEmbedURL(t *testing.T) {
140140
controlEntry := &model.Entry{
141141
URL: "https://www.youtube.com/watch?v=1234",
142142
Title: `A title`,
143-
Content: `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/1234" allowfullscreen></iframe><br>Video Description`,
143+
Content: `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/1234" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
144144
}
145145
testEntry := &model.Entry{
146146
URL: "https://www.youtube.com/watch?v=1234",
@@ -159,7 +159,7 @@ func TestRewriteYoutubeVideoLinkUsingInvidious(t *testing.T) {
159159
controlEntry := &model.Entry{
160160
URL: "https://www.youtube.com/watch?v=1234",
161161
Title: `A title`,
162-
Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1234" allowfullscreen></iframe><br>Video Description`,
162+
Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1234" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
163163
}
164164
testEntry := &model.Entry{
165165
URL: "https://www.youtube.com/watch?v=1234",
@@ -179,7 +179,7 @@ func TestRewriteYoutubeShortLinkUsingInvidious(t *testing.T) {
179179
controlEntry := &model.Entry{
180180
URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
181181
Title: `A title`,
182-
Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1LUWKWZkPjo" allowfullscreen></iframe><br>Video Description`,
182+
Content: `<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/1LUWKWZkPjo" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video Description`,
183183
}
184184
testEntry := &model.Entry{
185185
URL: "https://www.youtube.com/shorts/1LUWKWZkPjo",
@@ -199,16 +199,16 @@ func TestAddYoutubeVideoFromId(t *testing.T) {
199199

200200
scenarios := map[string]string{
201201
// Test with single YouTube ID
202-
`Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/9uASADiYe_8" allowfullscreen></iframe><br>Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`,
202+
`Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/9uASADiYe_8" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube ID <script type="text/javascript" data-reactid="6">window.__APOLLO_STATE__ = {youtube_id: "9uASADiYe_8"}</script>`,
203203

204204
// Test with multiple YouTube IDs
205-
`Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br><iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/jNQXAC9IVRw" allowfullscreen></iframe><br>Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`,
205+
`Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br><iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/jNQXAC9IVRw" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Content with youtube_id: "dQw4w9WgXcQ" and youtube_id: "jNQXAC9IVRw"`,
206206

207207
// Test with YouTube ID using equals sign
208-
`Some content with youtube_id = "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id = "dQw4w9WgXcQ"`,
208+
`Some content with youtube_id = "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube_id = "dQw4w9WgXcQ"`,
209209

210210
// Test with spaces around delimiters
211-
`Some content with youtube_id : "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id : "dQw4w9WgXcQ"`,
211+
`Some content with youtube_id : "dQw4w9WgXcQ"`: `<iframe width="650" height="350" frameborder="0" src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube_id : "dQw4w9WgXcQ"`,
212212

213213
// Test with YouTube ID without quotes (regex requires quotes)
214214
`Some content with youtube_id: dQw4w9WgXcQ and more`: `Some content with youtube_id: dQw4w9WgXcQ and more`,
@@ -245,7 +245,7 @@ func TestAddYoutubeVideoFromIdWithCustomEmbedURL(t *testing.T) {
245245
}
246246

247247
input := `Some content with youtube_id: "dQw4w9WgXcQ"`
248-
expected := `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some content with youtube_id: "dQw4w9WgXcQ"`
248+
expected := `<iframe width="650" height="350" frameborder="0" src="https://invidious.custom/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some content with youtube_id: "dQw4w9WgXcQ"`
249249

250250
actual := addYoutubeVideoFromId(input)
251251
if actual != expected {
@@ -260,35 +260,35 @@ func TestAddInvidiousVideo(t *testing.T) {
260260
// Test with various Invidious instances
261261
"https://invidious.io/watch?v=dQw4w9WgXcQ": {
262262
"Some video content",
263-
`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Some video content`,
263+
`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Some video content`,
264264
},
265265
"https://yewtu.be/watch?v=jNQXAC9IVRw": {
266266
"Another video description",
267-
`<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/jNQXAC9IVRw" allowfullscreen></iframe><br>Another video description`,
267+
`<iframe width="650" height="350" frameborder="0" src="https://yewtu.be/embed/jNQXAC9IVRw" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Another video description`,
268268
},
269269
"http://invidious.snopyta.org/watch?v=dQw4w9WgXcQ": {
270270
"HTTP instance test",
271-
`<iframe width="650" height="350" frameborder="0" src="https://invidious.snopyta.org/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>HTTP instance test`,
271+
`<iframe width="650" height="350" frameborder="0" src="https://invidious.snopyta.org/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>HTTP instance test`,
272272
},
273273
"https://youtube.com/watch?v=dQw4w9WgXcQ": {
274274
"YouTube URL (also matches regex)",
275-
`<iframe width="650" height="350" frameborder="0" src="https://youtube.com/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>YouTube URL (also matches regex)`,
275+
`<iframe width="650" height="350" frameborder="0" src="https://youtube.com/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>YouTube URL (also matches regex)`,
276276
},
277277
"https://example.org/watch?v=dQw4w9WgXcQ": {
278278
"Any domain with watch pattern",
279-
`<iframe width="650" height="350" frameborder="0" src="https://example.org/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>Any domain with watch pattern`,
279+
`<iframe width="650" height="350" frameborder="0" src="https://example.org/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Any domain with watch pattern`,
280280
},
281281

282282
// Test with query parameters
283283
"https://invidious.io/watch?v=dQw4w9WgXcQ&t=30s": {
284284
"Video with timestamp",
285-
`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?t=30s" allowfullscreen></iframe><br>Video with timestamp`,
285+
`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?t=30s" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video with timestamp`,
286286
},
287287

288288
// Test with more complex query parameters
289289
"https://invidious.io/watch?v=dQw4w9WgXcQ&t=30s&autoplay=1": {
290290
"Video with multiple parameters",
291-
`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?autoplay=1&t=30s" allowfullscreen></iframe><br>Video with multiple parameters`,
291+
`<iframe width="650" height="350" frameborder="0" src="https://invidious.io/embed/dQw4w9WgXcQ?autoplay=1&t=30s" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>Video with multiple parameters`,
292292
},
293293

294294
// Test with non-matching URLs (should return content unchanged)
@@ -308,7 +308,7 @@ func TestAddInvidiousVideo(t *testing.T) {
308308
// Test with empty content
309309
"https://empty.invidious.io/watch?v=dQw4w9WgXcQ": {
310310
"",
311-
`<iframe width="650" height="350" frameborder="0" src="https://empty.invidious.io/embed/dQw4w9WgXcQ" allowfullscreen></iframe><br>`,
311+
`<iframe width="650" height="350" frameborder="0" src="https://empty.invidious.io/embed/dQw4w9WgXcQ" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe><br>`,
312312
},
313313
}
314314

@@ -1257,14 +1257,14 @@ func TestStripImageQueryParams(t *testing.T) {
12571257
<p>Article content with images having query parameters:</p>
12581258
<img src="https://example.org/images/image1.jpg?width=200&height=113&q=80&blur=90" alt="Image with params">
12591259
<img src="https://example.org/images/image2.jpg?width=800&height=600&q=85" alt="Another image with params">
1260-
1260+
12611261
<p>More images with various query parameters:</p>
12621262
<img src="https://example.org/image123.jpg?blur=50&size=small&format=webp" alt="Complex query params">
12631263
<img src="https://example.org/image123.jpg?size=large&quality=95&cache=123" alt="Different params">
1264-
1264+
12651265
<p>Image without query parameters:</p>
12661266
<img src="https://example.org/single-image.jpg" alt="Clean image">
1267-
1267+
12681268
<p>Images with various other params:</p>
12691269
<img src="https://example.org/normal1.jpg?width=300&format=jpg" alt="Normal 1">
12701270
<img src="https://example.org/normal1.jpg?width=600&quality=high" alt="Normal 2">
@@ -1278,14 +1278,14 @@ func TestStripImageQueryParams(t *testing.T) {
12781278
<p>Article content with images having query parameters:</p>
12791279
<img src="https://example.org/images/image1.jpg" alt="Image with params"/>
12801280
<img src="https://example.org/images/image2.jpg?width=800&amp;height=600&amp;q=85" alt="Another image with params"/>
1281-
1281+
12821282
<p>More images with various query parameters:</p>
12831283
<img src="https://example.org/image123.jpg" alt="Complex query params"/>
12841284
<img src="https://example.org/image123.jpg?size=large&amp;quality=95&amp;cache=123" alt="Different params"/>
1285-
1285+
12861286
<p>Image without query parameters:</p>
12871287
<img src="https://example.org/single-image.jpg" alt="Clean image"/>
1288-
1288+
12891289
<p>Images with various other params:</p>
12901290
<img src="https://example.org/normal1.jpg?width=300&amp;format=jpg" alt="Normal 1"/>
12911291
<img src="https://example.org/normal1.jpg?width=600&amp;quality=high" alt="Normal 2"/>
@@ -1327,17 +1327,17 @@ func TestStripImageQueryParamsEdgeCases(t *testing.T) {
13271327
Title: `Edge Cases`,
13281328
Content: `
13291329
<p>Edge cases for image query parameter stripping:</p>
1330-
1330+
13311331
<!-- Various query parameters -->
13321332
<img src="https://example.org/image1.jpg?blur=80&width=300" alt="Multiple params">
1333-
1333+
13341334
<!-- Complex query parameters -->
13351335
<img src="https://example.org/image2.jpg?BLUR=60&format=webp&cache=123" alt="Complex params">
13361336
<img src="https://example.org/image3.jpg?quality=high&version=2" alt="Other params">
1337-
1337+
13381338
<!-- Query params in middle of string -->
13391339
<img src="https://example.org/image4.jpg?size=large&blur=30&format=webp&quality=90" alt="Middle params">
1340-
1340+
13411341
<!-- Image without query params -->
13421342
<img src="https://example.org/clean.jpg" alt="Clean image">
13431343
`,
@@ -1347,17 +1347,17 @@ func TestStripImageQueryParamsEdgeCases(t *testing.T) {
13471347
URL: "https://example.org/article",
13481348
Title: `Edge Cases`,
13491349
Content: `<p>Edge cases for image query parameter stripping:</p>
1350-
1350+
13511351
<!-- Various query parameters -->
13521352
<img src="https://example.org/image1.jpg" alt="Multiple params"/>
1353-
1353+
13541354
<!-- Complex query parameters -->
13551355
<img src="https://example.org/image2.jpg?BLUR=60&amp;format=webp&amp;cache=123" alt="Complex params"/>
13561356
<img src="https://example.org/image3.jpg?quality=high&amp;version=2" alt="Other params"/>
1357-
1357+
13581358
<!-- Query params in middle of string -->
13591359
<img src="https://example.org/image4.jpg" alt="Middle params"/>
1360-
1360+
13611361
<!-- Image without query params -->
13621362
<img src="https://example.org/clean.jpg" alt="Clean image"/>
13631363
`,
@@ -1375,7 +1375,7 @@ func TestStripImageQueryParamsSimple(t *testing.T) {
13751375
Title: `Simple Test`,
13761376
Content: `
13771377
<p>Testing query parameter stripping:</p>
1378-
1378+
13791379
<!-- Images with various query parameters -->
13801380
<img src="https://example.org/test1.jpg?blur=0&width=300" alt="With blur zero">
13811381
<img src="https://example.org/test2.jpg?blur=50&width=300&format=webp" alt="With blur fifty">
@@ -1388,7 +1388,7 @@ func TestStripImageQueryParamsSimple(t *testing.T) {
13881388
URL: "https://example.org/article",
13891389
Title: `Simple Test`,
13901390
Content: `<p>Testing query parameter stripping:</p>
1391-
1391+
13921392
<!-- Images with various query parameters -->
13931393
<img src="https://example.org/test1.jpg?blur=0&amp;width=300" alt="With blur zero"/>
13941394
<img src="https://example.org/test2.jpg" alt="With blur fifty"/>

internal/reader/sanitizer/sanitizer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ var (
4545
"h5": {"id"},
4646
"h6": {"id"},
4747
"hr": {},
48-
"iframe": {"width", "height", "frameborder", "src", "allowfullscreen"},
48+
"iframe": {"width", "height", "frameborder", "src", "allowfullscreen", "referrerpolicy"},
4949
"img": {"alt", "title", "src", "srcset", "sizes", "width", "height", "fetchpriority", "decoding"},
5050
"ins": {},
5151
"kbd": {},

internal/reader/sanitizer/sanitizer_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,18 @@ func TestIFrameWithChildElements(t *testing.T) {
457457
}
458458
}
459459

460+
func TestIFrameWithReferrerPolicy(t *testing.T) {
461+
config.Opts = config.NewConfigOptions()
462+
463+
input := `<iframe src="https://www.youtube.com/embed/test123" referrerpolicy="strict-origin-when-cross-origin"></iframe>`
464+
expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
465+
output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
466+
467+
if expected != output {
468+
t.Errorf(`Wrong output: %q != %q`, expected, output)
469+
}
470+
}
471+
460472
func TestLinkWithTarget(t *testing.T) {
461473
input := `<p>This link is <a href="http://example.org/index.html">an anchor</a></p>`
462474
expected := `<p>This link is <a href="http://example.org/index.html" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">an anchor</a></p>`

0 commit comments

Comments
 (0)