Changeset 255533 in webkit
- Timestamp:
- Jan 31, 2020 4:47:57 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r255532 r255533 1 2020-01-31 David Quesada <david_quesada@apple.com> 2 3 REGRESSION(r252185): NetworkSessionCocoa cancels downloads that receive authentication challenges 4 https://bugs.webkit.org/show_bug.cgi?id=206984 5 rdar://problem/58999654 6 7 Reviewed by Brady Eidson. 8 9 r252185 changed the early return in WKNetworkSessionDelegate's -...task:didReceiveChallenge:... method 10 from "cancel the task and return early if self has no _session" to "cancel the task and return early 11 if we can't determine the network session for the given data task". When this method is called for 12 an NSURLSessionDownloadTask, this early return is hit because there is no NetworkDataTaskCocoa 13 for an active download. As a result, the download is canceled when it might have otherwise been able 14 to proceed. 15 16 Fix this by adding a code path to fetch the NetworkSession associated with the Download when an 17 NSURLSessionDownloadTask receives an authentication challenge. This ensures we can actually handle 18 the challenge appropriately and not just cancel the task. 19 20 * NetworkProcess/Downloads/Download.h: 21 (WebKit::Download::sessionID const): 22 Expose the session ID so we can use it to look up the NetworkSession for a Download. 23 * NetworkProcess/cocoa/NetworkSessionCocoa.mm: 24 (-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]): 25 Remove an unnecessary redeclaration of networkDataTask, and also an unneeded assertion that 26 networkDataTask != nullptr. Even if this is the case, the code that eventually handles this 27 task will null check it and handle the challenge as a websocket task or download task 28 based on the taskIdentifier. 29 1 30 2020-01-31 Wenson Hsieh <wenson_hsieh@apple.com> 2 31 -
trunk/Source/WebKit/NetworkProcess/Downloads/Download.h
r250521 r255533 83 83 84 84 DownloadID downloadID() const { return m_downloadID; } 85 PAL::SessionID sessionID() const { return m_sessionID; } 85 86 const String& suggestedName() const { return m_suggestedName; } 86 87 -
trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
r255527 r255533 614 614 auto* networkDataTask = [self existingTask:task]; 615 615 auto* sessionCocoa = networkDataTask ? static_cast<NetworkSessionCocoa*>(networkDataTask->networkSession()) : nullptr; 616 if (!networkDataTask) { 617 ASSERT(!sessionCocoa); 618 auto downloadID = _sessionWrapper->downloadMap.get(task.taskIdentifier); 619 auto download = downloadID.downloadID() ? _session->networkProcess().downloadManager().download(downloadID) : nil; 620 sessionCocoa = download ? static_cast<NetworkSessionCocoa*>(_session->networkProcess().networkSession(download->sessionID())) : nil; 621 } 616 622 if (!sessionCocoa || [task state] == NSURLSessionTaskStateCanceling) { 617 623 completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); … … 652 658 if (sessionCocoa->fastServerTrustEvaluationEnabled() && negotiatedLegacyTLS == NegotiatedLegacyTLS::No) { 653 659 #if HAVE(CFNETWORK_NSURLSESSION_STRICTRUSTEVALUATE) 654 auto* networkDataTask = [self existingTask:task];655 ASSERT(networkDataTask);656 660 auto decisionHandler = makeBlockPtr([weakSelf = WeakObjCPtr<WKNetworkSessionDelegate>(self), sessionCocoa = makeWeakPtr(sessionCocoa), completionHandler = makeBlockPtr(completionHandler), taskIdentifier, networkDataTask = makeRefPtr(networkDataTask), negotiatedLegacyTLS](NSURLAuthenticationChallenge *challenge, OSStatus trustResult) mutable { 657 661 auto strongSelf = weakSelf.get(); -
trunk/Tools/ChangeLog
r255532 r255533 1 2020-01-31 David Quesada <david_quesada@apple.com> 2 3 REGRESSION(r252185): NetworkSessionCocoa cancels downloads that receive authentication challenges 4 https://bugs.webkit.org/show_bug.cgi?id=206984 5 rdar://problem/58999654 6 7 Reviewed by Brady Eidson. 8 9 Add an API test for a resumed download that receives an authentication challenge. The download 10 delegate should be asked to handle the challenge, and the download should be able to finish. 11 12 * TestWebKitAPI/Tests/WebKitCocoa/Download.mm: 13 (-[DownloadCancelingDelegate _download:decideDestinationWithSuggestedFilename:completionHandler:]): 14 (-[DownloadCancelingDelegate _download:didReceiveData:]): 15 (-[DownloadCancelingDelegate _downloadDidCancel:]): 16 (-[AuthenticationChallengeHandlingDelegate _download:didReceiveAuthenticationChallenge:completionHandler:]): 17 (-[AuthenticationChallengeHandlingDelegate _downloadDidFinish:]): 18 (TEST): 19 1 20 2020-01-31 Wenson Hsieh <wenson_hsieh@apple.com> 2 21 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Download.mm
r250521 r255533 1030 1030 } 1031 1031 1032 @interface DownloadCancelingDelegate : NSObject <_WKDownloadDelegate> 1033 @property (readonly) RetainPtr<NSData> resumeData; 1034 @property (readonly) RetainPtr<NSString> path; 1035 @end 1036 1037 @implementation DownloadCancelingDelegate 1038 1039 - (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler 1040 { 1041 FileSystem::PlatformFileHandle fileHandle; 1042 _path = FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle); 1043 EXPECT_TRUE(fileHandle != FileSystem::invalidPlatformFileHandle); 1044 FileSystem::closeFile(fileHandle); 1045 completionHandler(YES, _path.get()); 1046 } 1047 1048 - (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length 1049 { 1050 EXPECT_EQ(length, 5000ULL); 1051 [download cancel]; 1052 } 1053 1054 - (void)_downloadDidCancel:(_WKDownload *)download 1055 { 1056 EXPECT_NOT_NULL(download.resumeData); 1057 _resumeData = download.resumeData; 1058 isDone = true; 1059 } 1060 1061 @end 1062 1063 @interface AuthenticationChallengeHandlingDelegate : NSObject <_WKDownloadDelegate> 1064 @end 1065 1066 @implementation AuthenticationChallengeHandlingDelegate { 1067 bool _didReceiveAuthenticationChallenge; 1068 } 1069 1070 - (void)_download:(_WKDownload *)download didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential*))completionHandler 1071 { 1072 _didReceiveAuthenticationChallenge = true; 1073 completionHandler(NSURLSessionAuthChallengeUseCredential, nil); 1074 } 1075 1076 - (void)_downloadDidFinish:(_WKDownload *)download 1077 { 1078 EXPECT_TRUE(_didReceiveAuthenticationChallenge); 1079 isDone = true; 1080 } 1081 1082 @end 1083 1084 TEST(_WKDownload, ResumedDownloadCanHandleAuthenticationChallenge) 1085 { 1086 using namespace TestWebKitAPI; 1087 1088 std::atomic<bool> receivedFirstConnection { false }; 1089 1090 TCPServer server([&](int socket) { 1091 if (!receivedFirstConnection.exchange(true)) { 1092 TCPServer::read(socket); 1093 1094 const char* responseHeader = 1095 "HTTP/1.1 200 OK\r\n" 1096 "ETag: test\r\n" 1097 "Content-Length: 10000\r\n\r\n"; 1098 TCPServer::write(socket, responseHeader, strlen(responseHeader)); 1099 1100 char data[5000]; 1101 memset(data, 0, 5000); 1102 TCPServer::write(socket, data, 5000); 1103 1104 // Wait for the client to cancel the download before closing the connection. 1105 Util::run(&isDone); 1106 } else { 1107 TCPServer::read(socket); 1108 const char* challengeHeader = 1109 "HTTP/1.1 401 Unauthorized\r\n" 1110 "Date: Sat, 23 Mar 2019 06:29:01 GMT\r\n" 1111 "Content-Length: 0\r\n" 1112 "WWW-Authenticate: Basic realm=\"testrealm\"\r\n\r\n"; 1113 TCPServer::write(socket, challengeHeader, strlen(challengeHeader)); 1114 1115 TCPServer::read(socket); 1116 1117 const char* responseHeader = 1118 "HTTP/1.1 206 Partial Content\r\n" 1119 "ETag: test\r\n" 1120 "Content-Range: bytes 5000-9999/10000\r\n" 1121 "Content-Length: 5000\r\n\r\n"; 1122 TCPServer::write(socket, responseHeader, strlen(responseHeader)); 1123 1124 char data[5000]; 1125 memset(data, 1, 5000); 1126 TCPServer::write(socket, data, 5000); 1127 } 1128 }, 2); 1129 1130 auto processPool = adoptNS([[WKProcessPool alloc] init]); 1131 auto websiteDataStore = adoptNS([WKWebsiteDataStore defaultDataStore]); 1132 1133 auto delegate1 = adoptNS([[DownloadCancelingDelegate alloc] init]); 1134 [processPool _setDownloadDelegate:delegate1.get()]; 1135 1136 isDone = false; 1137 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]; 1138 [processPool _downloadURLRequest:request websiteDataStore:websiteDataStore.get() originatingWebView:nil]; 1139 1140 Util::run(&isDone); 1141 1142 isDone = false; 1143 auto delegate2 = adoptNS([[AuthenticationChallengeHandlingDelegate alloc] init]); 1144 [processPool _setDownloadDelegate:delegate2.get()]; 1145 [processPool _resumeDownloadFromData:[delegate1 resumeData].get() websiteDataStore:websiteDataStore.get() path:[delegate1 path].get() originatingWebView:nil]; 1146 1147 Util::run(&isDone); 1148 } 1149 1032 1150 #endif // PLATFORM(MAC) || PLATFORM(IOS)
Note: See TracChangeset
for help on using the changeset viewer.