api/stream/internal: workaround for wrong bsky content-type, refactor

This commit is contained in:
wukko 2024-11-16 22:15:13 +06:00
parent b61b8c82a2
commit 606f0fd29a
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
2 changed files with 17 additions and 11 deletions

View file

@ -53,7 +53,7 @@ function transformMediaPlaylist(streamInfo, hlsPlaylist) {
const HLS_MIME_TYPES = ["application/vnd.apple.mpegurl", "audio/mpegurl", "application/x-mpegURL"]; const HLS_MIME_TYPES = ["application/vnd.apple.mpegurl", "audio/mpegurl", "application/x-mpegURL"];
export function isHlsRequest (req) { export function isHlsResponse (req) {
return HLS_MIME_TYPES.includes(req.headers['content-type']); return HLS_MIME_TYPES.includes(req.headers['content-type']);
} }

View file

@ -1,7 +1,7 @@
import { request } from "undici"; import { request } from "undici";
import { Readable } from "node:stream"; import { Readable } from "node:stream";
import { closeRequest, getHeaders, pipe } from "./shared.js"; import { closeRequest, getHeaders, pipe } from "./shared.js";
import { handleHlsPlaylist, isHlsRequest } from "./internal-hls.js"; import { handleHlsPlaylist, isHlsResponse } from "./internal-hls.js";
const CHUNK_SIZE = BigInt(8e6); // 8 MB const CHUNK_SIZE = BigInt(8e6); // 8 MB
const min = (a, b) => a < b ? a : b; const min = (a, b) => a < b ? a : b;
@ -83,7 +83,7 @@ async function handleGenericStream(streamInfo, res) {
const cleanup = () => res.end(); const cleanup = () => res.end();
try { try {
const req = await request(streamInfo.url, { const fileResponse = await request(streamInfo.url, {
headers: { headers: {
...Object.fromEntries(streamInfo.headers), ...Object.fromEntries(streamInfo.headers),
host: undefined host: undefined
@ -93,22 +93,28 @@ async function handleGenericStream(streamInfo, res) {
maxRedirections: 16 maxRedirections: 16
}); });
res.status(req.statusCode); res.status(fileResponse.statusCode);
req.body.on('error', () => {}); fileResponse.body.on('error', () => {});
for (const [ name, value ] of Object.entries(req.headers)) { // bluesky's cdn responds with wrong content-type for the hls playlist,
if (!isHlsRequest(req) || name.toLowerCase() !== 'content-length') { // so we enforce it here until they fix it
const isHls = isHlsResponse(fileResponse)
|| (streamInfo.service === "bsky" && streamInfo.url.endsWith('.m3u8'));
for (const [ name, value ] of Object.entries(fileResponse.headers)) {
if (!isHls || name.toLowerCase() !== 'content-length') {
res.setHeader(name, value); res.setHeader(name, value);
} }
} }
if (req.statusCode < 200 || req.statusCode > 299) if (fileResponse.statusCode < 200 || fileResponse.statusCode > 299) {
return cleanup(); return cleanup();
}
if (isHlsRequest(req)) { if (isHls) {
await handleHlsPlaylist(streamInfo, req, res); await handleHlsPlaylist(streamInfo, fileResponse, res);
} else { } else {
pipe(req.body, res, cleanup); pipe(fileResponse.body, res, cleanup);
} }
} catch { } catch {
closeRequest(streamInfo.controller); closeRequest(streamInfo.controller);