Ask a video's own page for a thumbnail the listing lost
sxyprn signs its CDN paths with an expiry, and the URLs the listing hands us have generally passed theirs. They only look alive while Cloudflare still has the bytes: add a cache-buster to one that returns 200 and it returns 404, every time, for every one tried. The newest posts are the ones nobody fetched while the URL was valid, so they are the ones that arrive as holes in the grid -- which is exactly where this was reported. Neither route can help, because both ask for the same dead address, and the right one can't be derived: the token signs the whole path, so swapping `full.jpg` for `small.jpg` or `vid` for `img` is just another 404. The post page, though, always carries a freshly signed one in og:image. So when a thumbnail has failed every way we know to ask for it, /api/poster fetches that page and reads the picture off it -- streamed, capped, and only if what comes back is HTML, since a page URL that turns out to redirect to the video must cost one buffer rather than a download. Answers are cached, including "nothing", which is the honest answer for a post that has been deleted. Finding the page is the other half. A listing item points at the Hot Tub server's proxy, which answers by redirecting to the video, so there is no page there to read -- but the item also carries the Referer the media needs, and that names the site. Its origin plus the path the proxy was going to fetch is the page a browser would open. Also fixes what this exposed: the retry ladder disarmed itself on its last step, so the failure that means "the picture is gone, not the route" was never heard by anything. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MPZFnNdHbPGDTqQUNiE4ZN
This commit is contained in:
@@ -631,7 +631,7 @@ App.feed = App.feed || {};
|
||||
</div>
|
||||
`;
|
||||
const poster = pane.querySelector('.feed-poster');
|
||||
App.videos.attachThumbnail(poster, v.thumb);
|
||||
App.videos.attachThumbnail(poster, v.thumb, App.videos.sourcePageUrl(v));
|
||||
const slideVideo = pane.querySelector('.feed-video');
|
||||
bindTimeline(pane, slideVideo);
|
||||
bindSharedControls(pane, slideVideo, v);
|
||||
@@ -1110,7 +1110,7 @@ App.feed = App.feed || {};
|
||||
const titleText = pane.querySelector('.feed-title-text');
|
||||
if (titleText) titleText.textContent = v.title || '';
|
||||
const poster = pane.querySelector('.feed-poster');
|
||||
if (poster) App.videos.attachThumbnail(poster, v.thumb);
|
||||
if (poster) App.videos.attachThumbnail(poster, v.thumb, App.videos.sourcePageUrl(v));
|
||||
loadSlideSource(pane, v, true);
|
||||
setPipMetadata(v);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user