diff --git a/ios/Sources/GutenbergKit/Sources/Media/MediaUploadServer.swift b/ios/Sources/GutenbergKit/Sources/Media/MediaUploadServer.swift index 5b3c90c0b..d18cacae4 100644 --- a/ios/Sources/GutenbergKit/Sources/Media/MediaUploadServer.swift +++ b/ios/Sources/GutenbergKit/Sources/Media/MediaUploadServer.swift @@ -186,6 +186,10 @@ final class MediaUploadServer: Sendable { private static func passthroughResponse( _ request: HTTPServer.Request, query: String, context: UploadContext ) async throws -> HTTPResponse { + // As in `processAndUpload`: don't put bytes on the wire for a torn-down + // editor, regardless of whether the HTTP client honors cancellation. + try Task.checkCancellation() + Logger.uploadServer.debug("Passthrough: forwarding original request body to WordPress") guard let body = request.parsed.body, let contentType = request.parsed.header("Content-Type"), @@ -313,6 +317,13 @@ final class MediaUploadServer: Sendable { } } + // The editor was torn down (or the client disconnected) while we processed. + // Don't start an outbound upload whose response nobody will read — it would + // create an attachment neither GutenbergKit nor the host knows to clean up. + // Checking here rather than relying on the HTTP client to notice cancellation + // keeps this true for a host-injected `URLSessionProtocol` that doesn't. + try Task.checkCancellation() + // Step 2: Upload to remote WordPress if let delegate = context.uploadDelegate, let result = try await delegate.uploadFile(at: uploadURL, mimeType: uploadMimeType, filename: uploadFilename) {