⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 280875 in webkit


Ignore:
Timestamp:
Aug 10, 2021, 5:12:16 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

WebKitBlobResource error 1 exactly after 60 seconds when trying to read file input
https://bugs.webkit.org/show_bug.cgi?id=228683
<rdar://78448610>

Patch by Alex Christensen <achristensen@webkit.org> on 2021-08-10
Reviewed by Tim Horton.

To prevent UIKit from deleting our files to upload after 60 seconds, copy them to a temporary directory,
then delete the files when cleaning up the WKContentView.

I manually verified this makes the files able to upload after more than 60 seconds, then deletes them when you close the tab.

  • UIProcess/ios/WKContentView.h:
  • UIProcess/ios/WKContentView.mm:

(-[WKContentView dealloc]):
(-[WKContentView _removeTemporaryFilesIfNecessary]):
(-[WKContentView _removeTemporaryFilesWhenDeallocated:]):

  • UIProcess/ios/WKContentViewInteraction.h.orig: Added.
  • UIProcess/ios/WKContentViewInteraction.mm.orig: Added.
  • UIProcess/ios/forms/WKFileUploadPanel.mm:

(-[WKFileUploadPanel documentPicker:didPickDocumentsAtURLs:]):

Location:
trunk/Source/WebKit
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r280865 r280875  
     12021-08-10  Alex Christensen  <achristensen@webkit.org>
     2
     3        WebKitBlobResource error 1 exactly after 60 seconds when trying to read file input
     4        https://bugs.webkit.org/show_bug.cgi?id=228683
     5        <rdar://78448610>
     6
     7        Reviewed by Tim Horton.
     8
     9        To prevent UIKit from deleting our files to upload after 60 seconds, copy them to a temporary directory,
     10        then delete the files when cleaning up the WKContentView.
     11
     12        I manually verified this makes the files able to upload after more than 60 seconds, then deletes them when you close the tab.
     13
     14        * UIProcess/ios/WKContentView.h:
     15        * UIProcess/ios/WKContentView.mm:
     16        (-[WKContentView dealloc]):
     17        (-[WKContentView _removeTemporaryFilesIfNecessary]):
     18        (-[WKContentView _removeTemporaryFilesWhenDeallocated:]):
     19        * UIProcess/ios/WKContentViewInteraction.h.orig: Added.
     20        * UIProcess/ios/WKContentViewInteraction.mm.orig: Added.
     21        * UIProcess/ios/forms/WKFileUploadPanel.mm:
     22        (-[WKFileUploadPanel documentPicker:didPickDocumentsAtURLs:]):
     23
    1242021-08-10  Andres Gonzalez  <andresg_22@apple.com>
    225
  • trunk/Source/WebKit/UIProcess/ios/WKContentView.h

    r279711 r280875  
    113113
    114114- (void)_setAcceleratedCompositingRootView:(UIView *)rootView;
     115- (void)_removeTemporaryDirectoriesWhenDeallocated:(Vector<RetainPtr<NSURL>>&&)urls;
    115116
    116117- (void)_showInspectorHighlight:(const WebCore::InspectorOverlay::Highlight&)highlight;
  • trunk/Source/WebKit/UIProcess/ios/WKContentView.mm

    r279711 r280875  
    150150    uint64_t _pdfPrintCallbackID;
    151151    RetainPtr<CGPDFDocumentRef> _printedDocument;
     152    Vector<RetainPtr<NSURL>> _temporaryURLsToDeleteWhenDeallocated;
    152153}
    153154
     
    314315    WebKit::WebProcessPool::statistics().wkViewCount--;
    315316
     317    [self _removeTemporaryFilesIfNecessary];
     318   
    316319    [super dealloc];
     320}
     321
     322- (void)_removeTemporaryFilesIfNecessary
     323{
     324    if (_temporaryURLsToDeleteWhenDeallocated.isEmpty())
     325        return;
     326   
     327    auto deleteTemporaryFiles = makeBlockPtr([urls = std::exchange(_temporaryURLsToDeleteWhenDeallocated, { })] {
     328        ASSERT(!RunLoop::isMain());
     329        auto manager = adoptNS([[NSFileManager alloc] init]);
     330        auto coordinator = adoptNS([[NSFileCoordinator alloc] init]);
     331        for (auto& url : urls) {
     332            if (![manager fileExistsAtPath:[url path]])
     333                continue;
     334            NSError *error = nil;
     335            [coordinator coordinateWritingItemAtURL:url.get() options:NSFileCoordinatorWritingForDeleting error:&error byAccessor:^(NSURL *coordinatedURL) {
     336                NSError *error = nil;
     337                if (![manager removeItemAtURL:coordinatedURL error:&error] || error)
     338                    LOG_ERROR(OS_LOG_DEFAULT, "WKContentViewInteraction failed to remove file at path %@ with error %@", coordinatedURL.path, error);
     339            }];
     340            if (error)
     341                LOG_ERROR(OS_LOG_DEFAULT, "WKContentViewInteraction failed to coordinate removal of temporary file at path %@ with error %@", url, error);
     342        }
     343    });
     344
     345    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), deleteTemporaryFiles.get());
     346}
     347
     348- (void)_removeTemporaryDirectoriesWhenDeallocated:(Vector<RetainPtr<NSURL>>&&)urls
     349{
     350    _temporaryURLsToDeleteWhenDeallocated.appendVector(WTFMove(urls));
    317351}
    318352
  • trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm

    r279863 r280875  
    649649}
    650650
    651 - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls
     651
     652- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urlsFromUIKit
    652653{
    653654    ASSERT(urls.count);
    654655    [self _dismissDisplayAnimated:YES];
    655     [self _chooseFiles:urls displayString:displayStringForDocumentsAtURLs(urls) iconImage:iconForFile(urls[0]).get()];
     656
     657    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), makeBlockPtr([retainedSelf = retainPtr(self), urlsFromUIKit = retainPtr(urlsFromUIKit)] () mutable {
     658
     659        auto copyToNewTemporaryDirectory = [] (NSArray<NSURL *> *originalURLs) -> std::pair<RetainPtr<NSArray<NSURL *>>, Vector<RetainPtr<NSURL>>> {
     660            ASSERT(!RunLoop::isMain());
     661            auto maybeMovedURLs = adoptNS([[NSMutableArray alloc] initWithCapacity:originalURLs.count]);
     662            __block Vector<RetainPtr<NSURL>> temporaryURLs;
     663            auto manager = adoptNS([[NSFileManager alloc] init]);
     664            auto coordinator = adoptNS([[NSFileCoordinator alloc] init]);
     665            for (NSURL *originalURL in originalURLs) {
     666                NSError *error = nil;
     667                NSString *temporaryDirectory = FileSystem::createTemporaryDirectory(@"WKFileUploadPanel");
     668                if (!temporaryDirectory) {
     669                    LOG_ERROR("WKFileUploadPanel: Failed to make temporary directory");
     670                    [maybeMovedURLs addObject:originalURL];
     671                    continue;
     672                }
     673                NSString *filePath = [temporaryDirectory stringByAppendingPathComponent:originalURL.lastPathComponent];
     674                auto destinationFileURL = adoptNS([[NSURL alloc] initFileURLWithPath:filePath isDirectory:NO]);
     675                [coordinator coordinateWritingItemAtURL:originalURL options:NSFileCoordinatorWritingForMoving error:&error byAccessor:^(NSURL *coordinatedOriginalURL) {
     676                    NSError *error = nil;
     677                    if (![manager moveItemAtURL:coordinatedOriginalURL toURL:destinationFileURL.get() error:&error] || error) {
     678                        LOG_ERROR("WKFileUploadPanel: Failed to move file to new path %@ with error %@", destinationFileURL.get(), error);
     679                        // If moving fails, keep the original URL and our 60 second time limit before it is deleted. We tried our best to extend it.
     680                        [maybeMovedURLs addObject:coordinatedOriginalURL];
     681                    } else
     682                        [maybeMovedURLs addObject:destinationFileURL.get()];
     683                }];
     684                if (error) {
     685                    LOG_ERROR("WKFileUploadPanel: Failed to coordinate moving file with error %@", error);
     686                    // If moving fails, keep the original URL and our 60 second time limit before it is deleted. We tried our best to extend it.
     687                    [maybeMovedURLs addObject:originalURL];
     688                }
     689                temporaryURLs.append(adoptNS([[NSURL alloc] initFileURLWithPath:temporaryDirectory isDirectory:YES]));
     690            }
     691            return { WTFMove(maybeMovedURLs), WTFMove(temporaryURLs) };
     692        };
     693
     694        auto [maybeMovedURLs, temporaryURLs] = copyToNewTemporaryDirectory(urlsFromUIKit.get());
     695        [retainedSelf->_view _removeTemporaryDirectoriesWhenDeallocated:WTFMove(temporaryURLs)];
     696        RunLoop::main().dispatch([retainedSelf = WTFMove(retainedSelf), maybeMovedURLs = WTFMove(maybeMovedURLs)] {
     697            [retainedSelf _chooseFiles:maybeMovedURLs.get() displayString:displayStringForDocumentsAtURLs(maybeMovedURLs.get()) iconImage:iconForFile(maybeMovedURLs.get()[0]).get()];
     698        });
     699    }).get());
    656700}
    657701
Note: See TracChangeset for help on using the changeset viewer.