v0.4.37: percent-encode preload download URL so non-ASCII paths cache
All checks were successful
build / build (push) Successful in 8m8s
All checks were successful
build / build (push) Successful in 8m8s
VideoCache.download() opened the connection with URI.create(url).toURL() on the raw URL. URLs whose path has non-ASCII segments (e.g. the Korean ".../음악퀴즈/...") were sent unencoded, so the server answered HTTP 400 and every preload aborted — the disk cache stayed empty and clients fell back to live streaming for every video (instant on a fast host, 10s+/no-show on a slower remote client). FFmpeg tolerates the raw URL, masking the bug at playback time. Encode only the bytes put on the wire; the READY key, sha256 filename, and lookup() all keep the original url string so cache hits still match the anchor's raw URL. Verified: raw URL -> HTTP 400, encoded -> 200. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ org.gradle.configuration-cache=false
|
|||||||
|
|
||||||
# Mod
|
# Mod
|
||||||
mod_id=video_player
|
mod_id=video_player
|
||||||
mod_version=0.4.36
|
mod_version=0.4.37
|
||||||
maven_group=com.ejclaw.videoplayer
|
maven_group=com.ejclaw.videoplayer
|
||||||
archives_base_name=video_player
|
archives_base_name=video_player
|
||||||
|
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ public final class VideoCache {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
URLConnection raw = URI.create(url).toURL().openConnection();
|
URLConnection raw = URI.create(encodeForRequest(url)).toURL().openConnection();
|
||||||
raw.setConnectTimeout(10_000);
|
raw.setConnectTimeout(10_000);
|
||||||
raw.setReadTimeout(30_000);
|
raw.setReadTimeout(30_000);
|
||||||
raw.setRequestProperty("User-Agent", "video_player/" + VideoPlayerMod.MOD_ID);
|
raw.setRequestProperty("User-Agent", "video_player/" + VideoPlayerMod.MOD_ID);
|
||||||
@@ -522,6 +522,31 @@ public final class VideoCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Percent-encode any non-ASCII characters in the URL so Java's {@link HttpURLConnection}
|
||||||
|
* puts a valid request line on the wire. The stored cache key, the {@link #sha256(String)}
|
||||||
|
* filename, and the {@link #READY} map all keep the ORIGINAL {@code url} string — only the
|
||||||
|
* bytes actually sent in the HTTP request are encoded — so {@link #lookup(String)} still
|
||||||
|
* matches the anchor's raw URL.
|
||||||
|
*
|
||||||
|
* <p>Without this, a URL with a non-ASCII path segment (e.g. {@code .../음악퀴즈/...}) is sent
|
||||||
|
* verbatim and the server answers HTTP 400, so every preload fails silently and the disk
|
||||||
|
* cache stays empty — clients then fall back to live streaming for every video. FFmpeg
|
||||||
|
* (playback) tolerates the raw URL, which is why playback "works" while the cache never
|
||||||
|
* fills. The multi-arg {@link URI} constructor encodes each component; an already-encoded
|
||||||
|
* URL round-trips unchanged (decode-then-encode is idempotent for these paths). On any
|
||||||
|
* parse failure we fall back to the raw string rather than dropping the download.
|
||||||
|
*/
|
||||||
|
private static String encodeForRequest(String url) {
|
||||||
|
try {
|
||||||
|
URI u = URI.create(url);
|
||||||
|
URI enc = new URI(u.getScheme(), u.getAuthority(), u.getPath(), u.getQuery(), u.getFragment());
|
||||||
|
return enc.toASCIIString();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Best-effort filename extension from the URL path so FFmpeg's container probe gets a hint
|
* Best-effort filename extension from the URL path so FFmpeg's container probe gets a hint
|
||||||
* (e.g. {@code .webm} for a webm stream). Falls back to {@code .bin}.
|
* (e.g. {@code .webm} for a webm stream). Falls back to {@code .bin}.
|
||||||
|
|||||||
Reference in New Issue
Block a user