Skip to content

Commit 35f40b7

Browse files
committed
Lock keyAndVersionExtracted while being read/written.
1 parent ad08250 commit 35f40b7

File tree

1 file changed

+63
-58
lines changed

1 file changed

+63
-58
lines changed

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

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ private YoutubeParsingHelper() {
205205
private static String[] youtubeMusicKey;
206206

207207
private static boolean keyAndVersionExtracted = false;
208+
private static final Object KEY_AND_VERSION_EXTRACTED_LOCK = new Object();
208209
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
209210
private static Optional<Boolean> hardcodedClientVersionAndKeyValid = Optional.empty();
210211

@@ -575,80 +576,84 @@ public static boolean areHardcodedClientVersionAndKeyValid()
575576

576577
private static void extractClientVersionAndKeyFromSwJs()
577578
throws IOException, ExtractionException {
578-
if (keyAndVersionExtracted) {
579-
return;
580-
}
581-
final String url = "https://www.youtube.com/sw.js";
582-
final var headers = getOriginReferrerHeaders("https://www.youtube.com");
583-
final String response = getDownloader().get(url, headers).responseBody();
584-
try {
585-
clientVersion = getStringResultFromRegexArray(response,
586-
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
587-
key = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
588-
} catch (final Parser.RegexException e) {
589-
throw new ParsingException("Could not extract YouTube WEB InnerTube client version "
590-
+ "and API key from sw.js", e);
579+
synchronized (KEY_AND_VERSION_EXTRACTED_LOCK) {
580+
if (keyAndVersionExtracted) {
581+
return;
582+
}
583+
final String url = "https://www.youtube.com/sw.js";
584+
final var headers = getOriginReferrerHeaders("https://www.youtube.com");
585+
final String response = getDownloader().get(url, headers).responseBody();
586+
try {
587+
clientVersion = getStringResultFromRegexArray(response,
588+
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
589+
key = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
590+
} catch (final Parser.RegexException e) {
591+
throw new ParsingException("Could not extract YouTube WEB InnerTube client version "
592+
+ "and API key from sw.js", e);
593+
}
594+
keyAndVersionExtracted = true;
591595
}
592-
keyAndVersionExtracted = true;
593596
}
594597

595598
private static void extractClientVersionAndKeyFromHtmlSearchResultsPage()
596599
throws IOException, ExtractionException {
597-
// Don't extract the client version and the InnerTube key if it has been already extracted
598-
if (keyAndVersionExtracted) {
599-
return;
600-
}
600+
synchronized (KEY_AND_VERSION_EXTRACTED_LOCK) {
601+
// Don't extract the client version and the InnerTube key if it has been already extracted
602+
if (keyAndVersionExtracted) {
603+
return;
604+
}
601605

602-
// Don't provide a search term in order to have a smaller response
603-
final String url = "https://www.youtube.com/results?search_query=&ucbcb=1";
604-
final String html = getDownloader().get(url, getCookieHeader()).responseBody();
605-
final JsonObject initialData = getInitialData(html);
606-
final JsonArray serviceTrackingParams = initialData.getObject("responseContext")
607-
.getArray("serviceTrackingParams");
606+
// Don't provide a search term in order to have a smaller response
607+
final String url = "https://www.youtube.com/results?search_query=&ucbcb=1";
608+
final String html = getDownloader().get(url, getCookieHeader()).responseBody();
609+
final JsonObject initialData = getInitialData(html);
610+
final JsonArray serviceTrackingParams = initialData.getObject("responseContext")
611+
.getArray("serviceTrackingParams");
608612

609-
// Try to get version from initial data first
610-
final Stream<JsonObject> serviceTrackingParamsStream = serviceTrackingParams.stream()
611-
.filter(JsonObject.class::isInstance)
612-
.map(JsonObject.class::cast);
613+
// Try to get version from initial data first
614+
final Stream<JsonObject> serviceTrackingParamsStream = serviceTrackingParams.stream()
615+
.filter(JsonObject.class::isInstance)
616+
.map(JsonObject.class::cast);
617+
618+
clientVersion = getClientVersionFromServiceTrackingParam(
619+
serviceTrackingParamsStream, "CSI", "cver");
613620

614-
clientVersion = getClientVersionFromServiceTrackingParam(
615-
serviceTrackingParamsStream, "CSI", "cver");
621+
if (clientVersion == null) {
622+
try {
623+
clientVersion = getStringResultFromRegexArray(html,
624+
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
625+
} catch (final Parser.RegexException ignored) {
626+
}
627+
}
628+
629+
// Fallback to get a shortened client version which does not contain the last two
630+
// digits
631+
if (isNullOrEmpty(clientVersion)) {
632+
clientVersion = getClientVersionFromServiceTrackingParam(
633+
serviceTrackingParamsStream, "ECATCHER", "client.version");
634+
}
616635

617-
if (clientVersion == null) {
618636
try {
619-
clientVersion = getStringResultFromRegexArray(html,
620-
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
637+
key = getStringResultFromRegexArray(html, INNERTUBE_API_KEY_REGEXES, 1);
621638
} catch (final Parser.RegexException ignored) {
622639
}
623-
}
624-
625-
// Fallback to get a shortened client version which does not contain the last two
626-
// digits
627-
if (isNullOrEmpty(clientVersion)) {
628-
clientVersion = getClientVersionFromServiceTrackingParam(
629-
serviceTrackingParamsStream, "ECATCHER", "client.version");
630-
}
631640

632-
try {
633-
key = getStringResultFromRegexArray(html, INNERTUBE_API_KEY_REGEXES, 1);
634-
} catch (final Parser.RegexException ignored) {
635-
}
641+
if (isNullOrEmpty(key)) {
642+
throw new ParsingException(
643+
// CHECKSTYLE:OFF
644+
"Could not extract YouTube WEB InnerTube API key from HTML search results page");
645+
// CHECKSTYLE:ON
646+
}
636647

637-
if (isNullOrEmpty(key)) {
638-
throw new ParsingException(
639-
// CHECKSTYLE:OFF
640-
"Could not extract YouTube WEB InnerTube API key from HTML search results page");
641-
// CHECKSTYLE:ON
642-
}
648+
if (clientVersion == null) {
649+
throw new ParsingException(
650+
// CHECKSTYLE:OFF
651+
"Could not extract YouTube WEB InnerTube client version from HTML search results page");
652+
// CHECKSTYLE:ON
653+
}
643654

644-
if (clientVersion == null) {
645-
throw new ParsingException(
646-
// CHECKSTYLE:OFF
647-
"Could not extract YouTube WEB InnerTube client version from HTML search results page");
648-
// CHECKSTYLE:ON
655+
keyAndVersionExtracted = true;
649656
}
650-
651-
keyAndVersionExtracted = true;
652657
}
653658

654659
@Nullable

0 commit comments

Comments
 (0)