Changeset 192287 in webkit
- Timestamp:
- Nov 10, 2015, 6:29:13 PM (10 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r192284 r192287 1 2015-11-10 Alex Christensen <achristensen@webkit.org> 2 3 Implement authentication challenge handling when using NETWORK_SESSION 4 https://bugs.webkit.org/show_bug.cgi?id=150968 5 6 Reviewed by Antti Koivisto. 7 8 * NetworkProcess/NetworkLoad.cpp: 9 (WebKit::NetworkLoad::didReceiveChallenge): 10 Copy functionality from NetworkLoad::canAuthenticateAgainstProtectionSpaceAsync (which is used when we don't use NETWORK_SESSION) 11 because there is no canAuthenticateAgainstProtectionSpace delegate callback when using NSURLSession, according to 12 https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html 13 Instead, all authentication challenge callbacks go to URLSession:task:didReceiveChallenge:completionHandler: 14 because we do not implement URLSession:didReceiveChallenge:completionHandler: 15 * NetworkProcess/cocoa/NetworkSessionCocoa.mm: 16 (-[NetworkSessionDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]): 17 (-[NetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]): 18 (-[NetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]): 19 Make a block copy of the completion handlers so we can copy the std::functions that wrap them into HashMaps and call them later, 20 in this case we call the completion handler after the UIProcess gives us credentials for an authentication challenge. 21 * Shared/Authentication/AuthenticationManager.cpp: 22 (WebKit::AuthenticationManager::AuthenticationManager): 23 (WebKit::AuthenticationManager::addChallengeToChallengeMap): 24 (WebKit::AuthenticationManager::shouldCoalesceChallenge): 25 (WebKit::AuthenticationManager::coalesceChallengesMatching): 26 (WebKit::AuthenticationManager::didReceiveAuthenticationChallenge): 27 Fix an existing bug that caused multiple calls to addChallengeToChallengeMap for one challenge. This caused too many calls to 28 the AuthenticationClient methods, which did not cause a problem because they were not one-time-use block copies of completion handlers before. 29 (WebKit::AuthenticationManager::useCredentialForSingleChallenge): 30 (WebKit::AuthenticationManager::continueWithoutCredentialForChallenge): 31 (WebKit::AuthenticationManager::continueWithoutCredentialForSingleChallenge): 32 (WebKit::AuthenticationManager::cancelChallenge): 33 (WebKit::AuthenticationManager::cancelSingleChallenge): 34 (WebKit::AuthenticationManager::performDefaultHandling): 35 (WebKit::AuthenticationManager::performDefaultHandlingForSingleChallenge): 36 (WebKit::AuthenticationManager::rejectProtectionSpaceAndContinue): 37 (WebKit::AuthenticationManager::rejectProtectionSpaceAndContinueForSingleChallenge): 38 Call completion handlers which we stored in a HashMap before doing IPC if we are using NETWORK_SESSION, 39 which has completion handlers instead of continueSomething client calls. 40 * Shared/Authentication/AuthenticationManager.h: 41 (WebKit::AuthenticationManager::outstandingAuthenticationChallengeCount): 42 * Shared/Downloads/Download.cpp: 43 (WebKit::Download::didReceiveAuthenticationChallenge): 44 (WebKit::Download::didReceiveResponse): 45 * Shared/Downloads/DownloadAuthenticationClient.cpp: 46 (WebKit::DownloadAuthenticationClient::receivedChallengeRejection): 47 * Shared/Downloads/DownloadAuthenticationClient.h: 48 Add ifdefs for code related to downloading I will implement later. 49 1 50 2015-11-10 Simon Fraser <simon.fraser@apple.com> 2 51 -
trunk/Source/WebKit2/NetworkProcess/NetworkLoad.cpp
r192109 r192287 159 159 void NetworkLoad::didReceiveChallenge(const AuthenticationChallenge& challenge, std::function<void(AuthenticationChallengeDisposition, const Credential&)> completionHandler) 160 160 { 161 notImplemented(); 162 completionHandler(AuthenticationChallengeDisposition::PerformDefaultHandling, Credential()); 161 // NetworkResourceLoader does not know whether the request is cross origin, so Web process computes an applicable credential policy for it. 162 ASSERT(m_parameters.clientCredentialPolicy != DoNotAskClientForCrossOriginCredentials); 163 164 // Handle server trust evaluation at platform-level if requested, for performance reasons. 165 if (challenge.protectionSpace().authenticationScheme() == ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested 166 && !NetworkProcess::singleton().canHandleHTTPSServerTrustEvaluation()) { 167 completionHandler(AuthenticationChallengeDisposition::PerformDefaultHandling, Credential()); 168 return; 169 } 170 171 if (m_client.isSynchronous()) { 172 // FIXME: We should ask the WebProcess like the asynchronous case below does. 173 // This is currently impossible as the WebProcess is blocked waiting on this synchronous load. 174 // It's possible that we can jump straight to the UI process to resolve this. 175 completionHandler(AuthenticationChallengeDisposition::PerformDefaultHandling, Credential()); 176 return; 177 } 178 179 if (m_parameters.clientCredentialPolicy == DoNotAskClientForAnyCredentials) { 180 completionHandler(AuthenticationChallengeDisposition::UseCredential, Credential()); 181 return; 182 } 183 184 NetworkProcess::singleton().authenticationManager().didReceiveAuthenticationChallenge(m_parameters.webPageID, m_parameters.webFrameID, challenge, completionHandler); 163 185 } 164 186 -
trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm
r191998 r192287 95 95 if (auto* networkingTask = _session->dataTaskForIdentifier(task.taskIdentifier)) { 96 96 if (auto* client = networkingTask->client()) { 97 client->willPerformHTTPRedirection(response, request, ^(const WebCore::ResourceRequest& request) 97 auto completionHandlerCopy = Block_copy(completionHandler); 98 client->willPerformHTTPRedirection(response, request, [completionHandlerCopy](const WebCore::ResourceRequest& request) 98 99 { 99 completionHandler(request.nsURLRequest(WebCore::UpdateHTTPBody)); 100 completionHandlerCopy(request.nsURLRequest(WebCore::UpdateHTTPBody)); 101 Block_release(completionHandlerCopy); 100 102 } 101 103 ); … … 110 112 if (auto* networkingTask = _session->dataTaskForIdentifier(task.taskIdentifier)) { 111 113 if (auto* client = networkingTask->client()) { 112 client->didReceiveChallenge(challenge, ^(WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) 114 auto completionHandlerCopy = Block_copy(completionHandler); 115 client->didReceiveChallenge(challenge, [completionHandlerCopy](WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) 113 116 { 114 completionHandler(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential()); 117 completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential()); 118 Block_release(completionHandlerCopy); 115 119 } 116 120 ); … … 137 141 ASSERT(isMainThread()); 138 142 WebCore::ResourceResponse resourceResponse(response); 139 client->didReceiveResponse(resourceResponse, ^(WebKit::ResponseDisposition responseDisposition) 143 auto completionHandlerCopy = Block_copy(completionHandler); 144 client->didReceiveResponse(resourceResponse, [completionHandlerCopy](WebKit::ResponseDisposition responseDisposition) 140 145 { 141 completionHandler(toNSURLSessionResponseDisposition(responseDisposition)); 146 completionHandlerCopy(toNSURLSessionResponseDisposition(responseDisposition)); 147 Block_release(completionHandlerCopy); 142 148 } 143 149 ); -
trunk/Source/WebKit2/Shared/Authentication/AuthenticationManager.cpp
r188198 r192287 71 71 } 72 72 73 uint64_t AuthenticationManager::addChallengeToChallengeMap(const WebCore::AuthenticationChallenge& authenticationChallenge)73 uint64_t AuthenticationManager::addChallengeToChallengeMap(const Challenge& challenge) 74 74 { 75 75 ASSERT(RunLoop::isMain()); 76 76 77 77 uint64_t challengeID = generateAuthenticationChallengeID(); 78 m_challenges.set(challengeID, authenticationChallenge);78 m_challenges.set(challengeID, challenge); 79 79 return challengeID; 80 80 } … … 86 86 87 87 for (auto& item : m_challenges) { 88 if (item.key != challengeID && ProtectionSpace::compare(challenge.protectionSpace(), item.value. protectionSpace()))88 if (item.key != challengeID && ProtectionSpace::compare(challenge.protectionSpace(), item.value.challenge.protectionSpace())) 89 89 return true; 90 90 } … … 94 94 Vector<uint64_t> AuthenticationManager::coalesceChallengesMatching(uint64_t challengeID) const 95 95 { 96 AuthenticationChallengechallenge = m_challenges.get(challengeID);97 ASSERT(!challenge. isNull());96 auto challenge = m_challenges.get(challengeID); 97 ASSERT(!challenge.challenge.isNull()); 98 98 99 99 Vector<uint64_t> challengesToCoalesce; 100 100 challengesToCoalesce.append(challengeID); 101 101 102 if (!canCoalesceChallenge(challenge ))102 if (!canCoalesceChallenge(challenge.challenge)) 103 103 return challengesToCoalesce; 104 104 105 105 for (auto& item : m_challenges) { 106 if (item.key != challengeID && ProtectionSpace::compare(challenge. protectionSpace(), item.value.protectionSpace()))106 if (item.key != challengeID && ProtectionSpace::compare(challenge.challenge.protectionSpace(), item.value.challenge.protectionSpace())) 107 107 challengesToCoalesce.append(item.key); 108 108 } … … 116 116 ASSERT(frame->page()); 117 117 118 uint64_t challengeID = addChallengeToChallengeMap(authenticationChallenge); 118 uint64_t challengeID = addChallengeToChallengeMap({authenticationChallenge 119 #if USE(NETWORK_SESSION) 120 , ChallengeCompletionHandler() 121 #endif 122 }); 119 123 120 124 // Coalesce challenges in the same protection space. … … 126 130 127 131 #if ENABLE(NETWORK_PROCESS) 128 void AuthenticationManager::didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const AuthenticationChallenge& authenticationChallenge) 132 #if USE(NETWORK_SESSION) 133 void AuthenticationManager::didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const AuthenticationChallenge& authenticationChallenge, ChallengeCompletionHandler completionHandler) 129 134 { 130 135 ASSERT(pageID); 131 136 ASSERT(frameID); 132 137 133 uint64_t challengeID = addChallengeToChallengeMap( authenticationChallenge);138 uint64_t challengeID = addChallengeToChallengeMap({authenticationChallenge, completionHandler}); 134 139 if (shouldCoalesceChallenge(challengeID, authenticationChallenge)) 135 140 return; 136 141 137 m_process->send(Messages::NetworkProcessProxy::DidReceiveAuthenticationChallenge(pageID, frameID, authenticationChallenge, addChallengeToChallengeMap(authenticationChallenge))); 138 } 139 #endif 140 142 m_process->send(Messages::NetworkProcessProxy::DidReceiveAuthenticationChallenge(pageID, frameID, authenticationChallenge, challengeID)); 143 } 144 #endif 145 void AuthenticationManager::didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const AuthenticationChallenge& authenticationChallenge) 146 { 147 ASSERT(pageID); 148 ASSERT(frameID); 149 150 uint64_t challengeID = addChallengeToChallengeMap({authenticationChallenge 151 #if USE(NETWORK_SESSION) 152 , ChallengeCompletionHandler() 153 #endif 154 }); 155 if (shouldCoalesceChallenge(challengeID, authenticationChallenge)) 156 return; 157 158 m_process->send(Messages::NetworkProcessProxy::DidReceiveAuthenticationChallenge(pageID, frameID, authenticationChallenge, challengeID)); 159 } 160 #endif 161 162 #if !USE(NETWORK_SESSION) 141 163 void AuthenticationManager::didReceiveAuthenticationChallenge(Download* download, const AuthenticationChallenge& authenticationChallenge) 142 164 { 143 uint64_t challengeID = addChallengeToChallengeMap( authenticationChallenge);165 uint64_t challengeID = addChallengeToChallengeMap({authenticationChallenge}); 144 166 if (shouldCoalesceChallenge(challengeID, authenticationChallenge)) 145 167 return; 146 168 147 download->send(Messages::DownloadProxy::DidReceiveAuthenticationChallenge(authenticationChallenge, addChallengeToChallengeMap(authenticationChallenge))); 148 } 169 download->send(Messages::DownloadProxy::DidReceiveAuthenticationChallenge(authenticationChallenge, challengeID)); 170 } 171 #endif 149 172 150 173 // Currently, only Mac knows how to respond to authentication challenges with certificate info. … … 166 189 void AuthenticationManager::useCredentialForSingleChallenge(uint64_t challengeID, const Credential& credential, const CertificateInfo& certificateInfo) 167 190 { 168 AuthenticationChallenge challenge = m_challenges.take(challengeID); 169 ASSERT(!challenge.isNull()); 170 171 if (tryUseCertificateInfoForChallenge(challenge, certificateInfo)) 172 return; 173 174 AuthenticationClient* coreClient = challenge.authenticationClient(); 175 if (!coreClient) { 176 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 177 // We should not call Download::receivedCredential in the latter case. 178 Download::receivedCredential(challenge, credential); 179 return; 180 } 181 182 coreClient->receivedCredential(challenge, credential); 191 auto challenge = m_challenges.take(challengeID); 192 ASSERT(!challenge.challenge.isNull()); 193 194 if (tryUseCertificateInfoForChallenge(challenge.challenge, certificateInfo)) 195 return; 196 197 #if USE(NETWORK_SESSION) 198 // If there is a completion handler, then there is no AuthenticationClient. 199 // FIXME: Remove the use of AuthenticationClient in WebKit2 once NETWORK_SESSION is used for all loads. 200 if (challenge.completionHandler) { 201 challenge.completionHandler(AuthenticationChallengeDisposition::UseCredential, credential); 202 return; 203 } 204 #endif 205 206 AuthenticationClient* coreClient = challenge.challenge.authenticationClient(); 207 if (!coreClient) { 208 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 209 // We should not call Download::receivedCredential in the latter case. 210 Download::receivedCredential(challenge.challenge, credential); 211 return; 212 } 213 214 coreClient->receivedCredential(challenge.challenge, credential); 183 215 } 184 216 … … 193 225 void AuthenticationManager::continueWithoutCredentialForSingleChallenge(uint64_t challengeID) 194 226 { 195 AuthenticationChallenge challenge = m_challenges.take(challengeID); 196 ASSERT(!challenge.isNull()); 197 AuthenticationClient* coreClient = challenge.authenticationClient(); 198 if (!coreClient) { 199 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 200 // We should not call Download::receivedCredential in the latter case. 201 Download::receivedRequestToContinueWithoutCredential(challenge); 202 return; 203 } 204 205 coreClient->receivedRequestToContinueWithoutCredential(challenge); 227 auto challenge = m_challenges.take(challengeID); 228 ASSERT(!challenge.challenge.isNull()); 229 230 #if USE(NETWORK_SESSION) 231 if (challenge.completionHandler) { 232 challenge.completionHandler(AuthenticationChallengeDisposition::UseCredential, Credential()); 233 return; 234 } 235 #endif 236 237 AuthenticationClient* coreClient = challenge.challenge.authenticationClient(); 238 if (!coreClient) { 239 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 240 // We should not call Download::receivedCredential in the latter case. 241 Download::receivedRequestToContinueWithoutCredential(challenge.challenge); 242 return; 243 } 244 245 coreClient->receivedRequestToContinueWithoutCredential(challenge.challenge); 206 246 } 207 247 … … 216 256 void AuthenticationManager::cancelSingleChallenge(uint64_t challengeID) 217 257 { 218 AuthenticationChallenge challenge = m_challenges.take(challengeID); 219 ASSERT(!challenge.isNull()); 220 AuthenticationClient* coreClient = challenge.authenticationClient(); 221 if (!coreClient) { 222 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 223 // We should not call Download::receivedCredential in the latter case. 224 Download::receivedCancellation(challenge); 225 return; 226 } 227 228 coreClient->receivedCancellation(challenge); 258 auto challenge = m_challenges.take(challengeID); 259 ASSERT(!challenge.challenge.isNull()); 260 261 #if USE(NETWORK_SESSION) 262 if (challenge.completionHandler) { 263 challenge.completionHandler(AuthenticationChallengeDisposition::Cancel, Credential()); 264 return; 265 } 266 #endif 267 268 AuthenticationClient* coreClient = challenge.challenge.authenticationClient(); 269 if (!coreClient) { 270 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 271 // We should not call Download::receivedCredential in the latter case. 272 Download::receivedCancellation(challenge.challenge); 273 return; 274 } 275 276 coreClient->receivedCancellation(challenge.challenge); 229 277 } 230 278 … … 239 287 void AuthenticationManager::performDefaultHandlingForSingleChallenge(uint64_t challengeID) 240 288 { 241 AuthenticationChallenge challenge = m_challenges.take(challengeID); 242 ASSERT(!challenge.isNull()); 243 AuthenticationClient* coreClient = challenge.authenticationClient(); 244 if (!coreClient) { 245 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 246 // We should not call Download::receivedCredential in the latter case. 247 Download::receivedRequestToPerformDefaultHandling(challenge); 248 return; 249 } 250 251 coreClient->receivedRequestToPerformDefaultHandling(challenge); 289 auto challenge = m_challenges.take(challengeID); 290 ASSERT(!challenge.challenge.isNull()); 291 292 #if USE(NETWORK_SESSION) 293 if (challenge.completionHandler) { 294 challenge.completionHandler(AuthenticationChallengeDisposition::PerformDefaultHandling, Credential()); 295 return; 296 } 297 #endif 298 299 AuthenticationClient* coreClient = challenge.challenge.authenticationClient(); 300 if (!coreClient) { 301 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 302 // We should not call Download::receivedCredential in the latter case. 303 Download::receivedRequestToPerformDefaultHandling(challenge.challenge); 304 return; 305 } 306 307 coreClient->receivedRequestToPerformDefaultHandling(challenge.challenge); 252 308 } 253 309 … … 262 318 void AuthenticationManager::rejectProtectionSpaceAndContinueForSingleChallenge(uint64_t challengeID) 263 319 { 264 AuthenticationChallenge challenge = m_challenges.take(challengeID); 265 ASSERT(!challenge.isNull()); 266 AuthenticationClient* coreClient = challenge.authenticationClient(); 267 if (!coreClient) { 268 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 269 // We should not call Download::receivedCredential in the latter case. 270 Download::receivedChallengeRejection(challenge); 271 return; 272 } 273 274 coreClient->receivedChallengeRejection(challenge); 320 auto challenge = m_challenges.take(challengeID); 321 ASSERT(!challenge.challenge.isNull()); 322 323 #if USE(NETWORK_SESSION) 324 if (challenge.completionHandler) { 325 challenge.completionHandler(AuthenticationChallengeDisposition::RejectProtectionSpace, Credential()); 326 return; 327 } 328 #endif 329 330 AuthenticationClient* coreClient = challenge.challenge.authenticationClient(); 331 if (!coreClient) { 332 // FIXME: The authentication client is null for downloads, but it can also be null for canceled loads. 333 // We should not call Download::receivedCredential in the latter case. 334 Download::receivedChallengeRejection(challenge.challenge); 335 return; 336 } 337 338 coreClient->receivedChallengeRejection(challenge.challenge); 275 339 } 276 340 -
trunk/Source/WebKit2/Shared/Authentication/AuthenticationManager.h
r187691 r192287 29 29 #include "MessageReceiver.h" 30 30 #include "NetworkProcessSupplement.h" 31 #include "NetworkSession.h" 31 32 #include "WebProcessSupplement.h" 32 33 #include <WebCore/AuthenticationChallenge.h> … … 53 54 static const char* supplementName(); 54 55 56 #if USE(NETWORK_SESSION) 57 typedef std::function<void(AuthenticationChallengeDisposition, const WebCore::Credential&)> ChallengeCompletionHandler; 58 void didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler); 59 #endif 55 60 // Called for resources in the WebProcess (NetworkProcess disabled) 56 61 void didReceiveAuthenticationChallenge(WebFrame*, const WebCore::AuthenticationChallenge&); … … 69 74 70 75 private: 76 struct Challenge { 77 WebCore::AuthenticationChallenge challenge; 78 #if USE(NETWORK_SESSION) 79 ChallengeCompletionHandler completionHandler; 80 #endif 81 }; 82 71 83 // IPC::MessageReceiver 72 84 virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override; … … 74 86 bool tryUseCertificateInfoForChallenge(const WebCore::AuthenticationChallenge&, const WebCore::CertificateInfo&); 75 87 76 uint64_t addChallengeToChallengeMap(const WebCore::AuthenticationChallenge&);88 uint64_t addChallengeToChallengeMap(const Challenge&); 77 89 bool shouldCoalesceChallenge(uint64_t challengeID, const WebCore::AuthenticationChallenge&) const; 78 90 … … 87 99 ChildProcess* m_process; 88 100 89 typedef HashMap<uint64_t, WebCore::AuthenticationChallenge> AuthenticationChallengeMap; 90 AuthenticationChallengeMap m_challenges; 101 HashMap<uint64_t, Challenge> m_challenges; 91 102 }; 92 103 -
trunk/Source/WebKit2/Shared/Downloads/Download.cpp
r185905 r192287 30 30 #include "Connection.h" 31 31 #include "DataReference.h" 32 #include "DownloadAuthenticationClient.h"33 32 #include "DownloadProxyMessages.h" 34 33 #include "DownloadManager.h" 35 34 #include "SandboxExtension.h" 36 35 #include "WebCoreArgumentCoders.h" 36 #include <WebCore/NotImplemented.h> 37 38 #if !USE(NETWORK_SESSION) 39 #include "DownloadAuthenticationClient.h" 40 #endif 37 41 38 42 using namespace WebCore; … … 64 68 void Download::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge) 65 69 { 70 #if USE(NETWORK_SESSION) 71 notImplemented(); 72 #else 66 73 m_downloadManager.downloadsAuthenticationManager().didReceiveAuthenticationChallenge(this, authenticationChallenge); 74 #endif 67 75 } 68 76 -
trunk/Source/WebKit2/Shared/Downloads/DownloadAuthenticationClient.cpp
r169782 r192287 26 26 #include "config.h" 27 27 #include "DownloadAuthenticationClient.h" 28 29 #if !USE(NETWORK_SESSION) 28 30 29 31 #include "Download.h" … … 65 67 66 68 } // namespace WebKit 69 70 #endif -
trunk/Source/WebKit2/Shared/Downloads/DownloadAuthenticationClient.h
r186566 r192287 26 26 #ifndef DownloadAuthenticationClient_h 27 27 #define DownloadAuthenticationClient_h 28 29 #if !USE(NETWORK_SESSION) 28 30 29 31 #include <WebCore/AuthenticationClient.h> … … 66 68 } // namespace WebKit 67 69 70 #endif // !USE(NETWORK_SESSION) 71 68 72 #endif // DownloadAuthenticationClient_h
Note:
See TracChangeset
for help on using the changeset viewer.