From 0299f4af97b2b8a3823c78937b7d86cab19518cb Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Thu, 25 Mar 2021 11:57:12 -0400 Subject: [PATCH 1/4] Disable CDN Tune-in "age" header check when `lowLatencyMode` is set to `false` Resolves #3680 --- src/loader/playlist-loader.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/loader/playlist-loader.ts b/src/loader/playlist-loader.ts index 385f8575a79..72d10024ca6 100644 --- a/src/loader/playlist-loader.ts +++ b/src/loader/playlist-loader.ts @@ -686,13 +686,17 @@ class PlaylistLoader { return; } - // Avoid repeated browser error log `Refused to get unsafe header "age"` when unnecessary or past attempts failed - const checkAgeHeader = this.checkAgeHeader && levelDetails.live; - const ageHeader: string | null = checkAgeHeader - ? loader.getResponseHeader('age') - : null; - levelDetails.ageHeader = ageHeader ? parseFloat(ageHeader) : 0; - this.checkAgeHeader = !!ageHeader; + if ( + this.checkAgeHeader && + levelDetails.live && + this.hls.config.lowLatencyMode + ) { + const ageHeader = loader.getResponseHeader('age'); + levelDetails.ageHeader = ageHeader ? parseFloat(ageHeader) : 0; + // Avoid repeated browser error log `Refused to get unsafe header "age"` when unnecessary or past attempts failed + // Add an "Access-Control-Expose-Headers: age" header to playlist responses to prevent this CORS error + this.checkAgeHeader = ageHeader !== null; + } switch (type) { case PlaylistContextType.MANIFEST: From 3a81d94750a56f9d829063a7fc56e1339d1d1f1c Mon Sep 17 00:00:00 2001 From: radiantmediaplayer Date: Fri, 26 Mar 2021 12:08:33 +0100 Subject: [PATCH 2/4] fix Refused to get unsafe header "age" in Chrome --- src/loader/playlist-loader.ts | 3 +-- src/utils/xhr-loader.ts | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/loader/playlist-loader.ts b/src/loader/playlist-loader.ts index 72d10024ca6..ce6fe62fb23 100644 --- a/src/loader/playlist-loader.ts +++ b/src/loader/playlist-loader.ts @@ -688,8 +688,7 @@ class PlaylistLoader { if ( this.checkAgeHeader && - levelDetails.live && - this.hls.config.lowLatencyMode + levelDetails.live ) { const ageHeader = loader.getResponseHeader('age'); levelDetails.ageHeader = ageHeader ? parseFloat(ageHeader) : 0; diff --git a/src/utils/xhr-loader.ts b/src/utils/xhr-loader.ts index 530b60243dc..ce6f2605d19 100644 --- a/src/utils/xhr-loader.ts +++ b/src/utils/xhr-loader.ts @@ -250,12 +250,8 @@ class XhrLoader implements Loader { } getResponseHeader(name: string): string | null { - if (this.loader) { - try { - return this.loader.getResponseHeader(name); - } catch (error) { - /* Could not get headers */ - } + if (this.loader && this.loader.getAllResponseHeaders().indexOf(name) >= 0) { + return this.loader.getResponseHeader(name); } return null; } From 8c4865a34fc4ae1d6b8302cb822378bdd58e40b5 Mon Sep 17 00:00:00 2001 From: radiantmediaplayer Date: Fri, 26 Mar 2021 15:19:44 +0100 Subject: [PATCH 3/4] Update playlist-loader.ts --- src/loader/playlist-loader.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/loader/playlist-loader.ts b/src/loader/playlist-loader.ts index ce6fe62fb23..ccbdeb607f2 100644 --- a/src/loader/playlist-loader.ts +++ b/src/loader/playlist-loader.ts @@ -686,10 +686,7 @@ class PlaylistLoader { return; } - if ( - this.checkAgeHeader && - levelDetails.live - ) { + if (this.checkAgeHeader && levelDetails.live) { const ageHeader = loader.getResponseHeader('age'); levelDetails.ageHeader = ageHeader ? parseFloat(ageHeader) : 0; // Avoid repeated browser error log `Refused to get unsafe header "age"` when unnecessary or past attempts failed From b9c427c43feee3a3d02443b09f27a636f1288b1a Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Fri, 26 Mar 2021 15:10:37 -0400 Subject: [PATCH 4/4] Safely read playlist response "age" header --- src/loader/playlist-loader.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/loader/playlist-loader.ts b/src/loader/playlist-loader.ts index ccbdeb607f2..4dfb45daac8 100644 --- a/src/loader/playlist-loader.ts +++ b/src/loader/playlist-loader.ts @@ -70,8 +70,6 @@ class PlaylistLoader { [key: string]: Loader; } = Object.create(null); - private checkAgeHeader: boolean = true; - constructor(hls: Hls) { this.hls = hls; this.registerListeners(); @@ -148,7 +146,6 @@ class PlaylistLoader { data: ManifestLoadingData ) { const { url } = data; - this.checkAgeHeader = true; this.load({ id: null, groupId: null, @@ -686,12 +683,9 @@ class PlaylistLoader { return; } - if (this.checkAgeHeader && levelDetails.live) { + if (levelDetails.live) { const ageHeader = loader.getResponseHeader('age'); levelDetails.ageHeader = ageHeader ? parseFloat(ageHeader) : 0; - // Avoid repeated browser error log `Refused to get unsafe header "age"` when unnecessary or past attempts failed - // Add an "Access-Control-Expose-Headers: age" header to playlist responses to prevent this CORS error - this.checkAgeHeader = ageHeader !== null; } switch (type) {