Skip to content

Commit e579898

Browse files
committed
Lock keyAndVersionExtracted while being read/written.
1 parent 3b632db commit e579898

File tree

1 file changed

+68
-60
lines changed

1 file changed

+68
-60
lines changed

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ private YoutubeParsingHelper() {
201201
private static String[] youtubeMusicKey;
202202

203203
private static boolean keyAndVersionExtracted = false;
204+
private static final Object KEY_AND_VERSION_EXTRACTED_LOCK = new Object();
204205
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
205206
private static Optional<Boolean> hardcodedClientVersionAndKeyValid = Optional.empty();
206207

@@ -619,82 +620,89 @@ public static boolean areHardcodedClientVersionAndKeyValid()
619620

620621
private static void extractClientVersionAndKeyFromSwJs()
621622
throws IOException, ExtractionException {
622-
if (keyAndVersionExtracted) {
623-
return;
624-
}
625-
final String url = "https://www.youtube.com/sw.js";
626-
final Map<String, List<String>> headers = new HashMap<>();
627-
headers.put("Origin", singletonList("https://www.youtube.com"));
628-
headers.put("Referer", singletonList("https://www.youtube.com"));
629-
final String response = getDownloader().get(url, headers).responseBody();
630-
try {
631-
clientVersion = getStringResultFromRegexArray(response,
632-
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
633-
key = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
634-
} catch (final Parser.RegexException e) {
635-
throw new ParsingException("Could not extract YouTube WEB InnerTube client version "
636-
+ "and API key from sw.js", e);
623+
synchronized (KEY_AND_VERSION_EXTRACTED_LOCK) {
624+
if (keyAndVersionExtracted) {
625+
return;
626+
}
627+
final String url = "https://www.youtube.com/sw.js";
628+
final Map<String, List<String>> headers = new HashMap<>();
629+
headers.put("Origin", singletonList("https://www.youtube.com"));
630+
headers.put("Referer", singletonList("https://www.youtube.com"));
631+
final String response = getDownloader().get(url, headers).responseBody();
632+
try {
633+
clientVersion = getStringResultFromRegexArray(response,
634+
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
635+
key = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
636+
} catch (final Parser.RegexException e) {
637+
throw new ParsingException("Could not extract YouTube WEB InnerTube client version "
638+
+ "and API key from sw.js", e);
639+
}
640+
keyAndVersionExtracted = true;
637641
}
638-
keyAndVersionExtracted = true;
639642
}
640643

641644
private static void extractClientVersionAndKeyFromHtmlSearchResultsPage()
642645
throws IOException, ExtractionException {
643-
// Don't extract the client version and the InnerTube key if it has been already extracted
644-
if (keyAndVersionExtracted) {
645-
return;
646-
}
647646

648-
// Don't provide a search term in order to have a smaller response
649-
final String url = "https://www.youtube.com/results?search_query=&ucbcb=1";
650-
final String html = getDownloader().get(url, getCookieHeader()).responseBody();
651-
final JsonObject initialData = getInitialData(html);
652-
final JsonArray serviceTrackingParams = initialData.getObject("responseContext")
653-
.getArray("serviceTrackingParams");
647+
synchronized (KEY_AND_VERSION_EXTRACTED_LOCK) {
654648

655-
// Try to get version from initial data first
656-
final Stream<JsonObject> serviceTrackingParamsStream = serviceTrackingParams.stream()
657-
.filter(JsonObject.class::isInstance)
658-
.map(JsonObject.class::cast);
649+
// Don't extract the client version and the InnerTube key
650+
// if it has been already extracted
651+
if (keyAndVersionExtracted) {
652+
return;
653+
}
659654

660-
clientVersion = getClientVersionFromServiceTrackingParam(
661-
serviceTrackingParamsStream, "CSI", "cver");
655+
// Don't provide a search term in order to have a smaller response
656+
final String url = "https://www.youtube.com/results?search_query=&ucbcb=1";
657+
final String html = getDownloader().get(url, getCookieHeader()).responseBody();
658+
final JsonObject initialData = getInitialData(html);
659+
final JsonArray serviceTrackingParams = initialData.getObject("responseContext")
660+
.getArray("serviceTrackingParams");
661+
662+
// Try to get version from initial data first
663+
final Stream<JsonObject> serviceTrackingParamsStream = serviceTrackingParams.stream()
664+
.filter(JsonObject.class::isInstance)
665+
.map(JsonObject.class::cast);
666+
667+
clientVersion = getClientVersionFromServiceTrackingParam(
668+
serviceTrackingParamsStream, "CSI", "cver");
669+
670+
if (clientVersion == null) {
671+
try {
672+
clientVersion = getStringResultFromRegexArray(html,
673+
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
674+
} catch (final Parser.RegexException ignored) {
675+
}
676+
}
677+
678+
// Fallback to get a shortened client version which does not contain the last two
679+
// digits
680+
if (isNullOrEmpty(clientVersion)) {
681+
clientVersion = getClientVersionFromServiceTrackingParam(
682+
serviceTrackingParamsStream, "ECATCHER", "client.version");
683+
}
662684

663-
if (clientVersion == null) {
664685
try {
665-
clientVersion = getStringResultFromRegexArray(html,
666-
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
686+
key = getStringResultFromRegexArray(html, INNERTUBE_API_KEY_REGEXES, 1);
667687
} catch (final Parser.RegexException ignored) {
668688
}
669-
}
670689

671-
// Fallback to get a shortened client version which does not contain the last two
672-
// digits
673-
if (isNullOrEmpty(clientVersion)) {
674-
clientVersion = getClientVersionFromServiceTrackingParam(
675-
serviceTrackingParamsStream, "ECATCHER", "client.version");
676-
}
677-
678-
try {
679-
key = getStringResultFromRegexArray(html, INNERTUBE_API_KEY_REGEXES, 1);
680-
} catch (final Parser.RegexException ignored) {
681-
}
690+
if (isNullOrEmpty(key)) {
691+
throw new ParsingException(
692+
// CHECKSTYLE:OFF
693+
"Could not extract YouTube WEB InnerTube API key from HTML search results page");
694+
// CHECKSTYLE:ON
695+
}
682696

683-
if (isNullOrEmpty(key)) {
684-
throw new ParsingException(
685-
// CHECKSTYLE:OFF
686-
"Could not extract YouTube WEB InnerTube API key from HTML search results page");
687-
// CHECKSTYLE:ON
688-
}
697+
if (clientVersion == null) {
698+
throw new ParsingException(
699+
// CHECKSTYLE:OFF
700+
"Could not extract YouTube WEB InnerTube client version from HTML search results page");
701+
// CHECKSTYLE:ON
702+
}
689703

690-
if (clientVersion == null) {
691-
throw new ParsingException(
692-
// CHECKSTYLE:OFF
693-
"Could not extract YouTube WEB InnerTube client version from HTML search results page");
694-
// CHECKSTYLE:ON
704+
keyAndVersionExtracted = true;
695705
}
696-
697-
keyAndVersionExtracted = true;
698706
}
699707

700708
@Nullable

0 commit comments

Comments
 (0)