From 4ea3d964968bdc7f659a9dc5767f6e52a3044f13 Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Wed, 4 Mar 2026 14:30:34 +0100 Subject: [PATCH] fix3 --- .../xtreamplayer/XtreamPlayerApplication.java | 60 ++++++++++++------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/main/java/cz/kamma/xtreamplayer/XtreamPlayerApplication.java b/src/main/java/cz/kamma/xtreamplayer/XtreamPlayerApplication.java index 7afe414..714cb9a 100644 --- a/src/main/java/cz/kamma/xtreamplayer/XtreamPlayerApplication.java +++ b/src/main/java/cz/kamma/xtreamplayer/XtreamPlayerApplication.java @@ -245,42 +245,56 @@ public final class XtreamPlayerApplication { } try { - HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(target) - .GET() - .timeout(Duration.ofSeconds(60)) - .header("User-Agent", firstNonBlank( - exchange.getRequestHeaders().getFirst("User-Agent"), - DEFAULT_BROWSER_UA - )) - .header("Accept", firstNonBlank( - exchange.getRequestHeaders().getFirst("Accept"), - "*/*" - )); - copyRequestHeaderIfPresent(exchange, requestBuilder, "Range"); - copyRequestHeaderIfPresent(exchange, requestBuilder, "If-Range"); - if (!sourceUrl.isBlank()) { - requestBuilder.header("Referer", sourceUrl); - String origin = originFromUrl(sourceUrl); - if (!origin.isBlank()) { - requestBuilder.header("Origin", origin); + List attempts = candidateUris(target); + HttpResponse response = null; + URI usedTarget = target; + for (URI candidate : attempts) { + HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(candidate) + .GET() + .timeout(Duration.ofSeconds(60)) + .header("User-Agent", firstNonBlank( + exchange.getRequestHeaders().getFirst("User-Agent"), + DEFAULT_BROWSER_UA + )) + .header("Accept", firstNonBlank( + exchange.getRequestHeaders().getFirst("Accept"), + "*/*" + )); + copyRequestHeaderIfPresent(exchange, requestBuilder, "Range"); + copyRequestHeaderIfPresent(exchange, requestBuilder, "If-Range"); + if (!sourceUrl.isBlank()) { + requestBuilder.header("Referer", sourceUrl); + String origin = originFromUrl(sourceUrl); + if (!origin.isBlank()) { + requestBuilder.header("Origin", origin); + } + } + HttpRequest request = requestBuilder.build(); + HttpResponse candidateResponse = HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofByteArray()); + response = candidateResponse; + usedTarget = candidate; + if (candidateResponse.statusCode() < 400) { + break; } } - HttpRequest request = requestBuilder.build(); - HttpResponse response = HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofByteArray()); + if (response == null) { + writeJson(exchange, 502, errorJson("Unable to proxy stream: empty upstream response.")); + return; + } String contentType = response.headers().firstValue("Content-Type").orElse("application/octet-stream"); byte[] body = response.body() == null ? new byte[0] : response.body(); if (response.statusCode() >= 400) { LOGGER.warn( "Stream proxy upstream returned status={} uri={} bytes={} contentType={}", response.statusCode(), - maskUri(target), + maskUri(usedTarget), body.length, contentType ); } - if (isHlsPlaylist(target, contentType)) { - String rewritten = rewritePlaylistForProxy(target, body); + if (isHlsPlaylist(usedTarget, contentType)) { + String rewritten = rewritePlaylistForProxy(usedTarget, body); exchange.getResponseHeaders().set("Content-Type", "application/vnd.apple.mpegurl; charset=utf-8"); writeBytes(exchange, response.statusCode(), rewritten.getBytes(StandardCharsets.UTF_8), "application/vnd.apple.mpegurl; charset=utf-8");