fix: prevent youtube metadata extraction timeout

This fixes an issue where node child processes spawned by yt-dlp would keep standard output pipes open, preventing the EOF event from firing and causing the application to hang until a 30s timeout occurred.
This commit is contained in:
NimBold
2026-06-11 04:24:40 +03:30
parent b4185306ce
commit a916ff3f92
2 changed files with 6 additions and 7 deletions
+2
View File
@@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Applied rate-limiting and text length bounds to the custom `firelink://` scheme to mitigate DoS and injection attempts.
### Fixes
- Fixed a metadata extraction timeout when downloading from YouTube by preventing child processes from holding process pipes open.
- Resolved an issue to correctly assign filenames for auto-captured downloads.
- Restored the UUID fallback for token generation to prevent silent failures if secure random byte generation fails.
- Hardened local API security by immediately rejecting requests if the expected pairing token is completely empty.
- Implemented a thread-safe cleanup mechanism for temporary directories to resolve a concurrency race condition during engine cancellation.
+4 -7
View File
@@ -452,25 +452,19 @@ private final class YTDLPMetadataProcess: @unchecked Sendable {
process.standardError = errorPipe
process.standardInput = nil
let readGroup = DispatchGroup()
readGroup.enter()
outputPipe.fileHandleForReading.readabilityHandler = { handle in
let data = handle.availableData
if data.isEmpty {
handle.readabilityHandler = nil
readGroup.leave()
} else {
outputBuffer.append(data)
}
}
readGroup.enter()
errorPipe.fileHandleForReading.readabilityHandler = { handle in
let data = handle.availableData
if data.isEmpty {
handle.readabilityHandler = nil
readGroup.leave()
} else {
errorBuffer.append(data)
}
@@ -481,7 +475,10 @@ private final class YTDLPMetadataProcess: @unchecked Sendable {
}
process.terminationHandler = { finishedProcess in
readGroup.notify(queue: .global()) {
// Allow a brief moment for final pipe data to flush
DispatchQueue.global().asyncAfter(deadline: .now() + 0.25) {
outputPipe.fileHandleForReading.readabilityHandler = nil
errorPipe.fileHandleForReading.readabilityHandler = nil
if finishedProcess.terminationStatus == 0 {
continuation.resume(returning: outputBuffer.data)
} else {