Changeset 230251 in webkit


Ignore:
Timestamp:
Apr 3, 2018 11:55:15 PM (6 years ago)
Author:
commit-queue@webkit.org
Message:

Remove unused libsoup ResourceHandle implementation
https://bugs.webkit.org/show_bug.cgi?id=184048

Patch by Alex Christensen <achristensen@webkit.org> on 2018-04-03
Reviewed by Michael Catanzaro.

This code is unused since r228901 so let's remove it!

  • platform/network/ResourceHandle.h:
  • platform/network/ResourceHandleInternal.h:

(WebCore::ResourceHandleInternal::ResourceHandleInternal):

  • platform/network/soup/ResourceHandleSoup.cpp:

(WebCore::ResourceHandle::~ResourceHandle):
(WebCore::ResourceHandleInternal::soupSession):
(WebCore::ResourceHandle::cancelledOrClientless):
(WebCore::ResourceHandle::ensureReadBuffer):
(WebCore::ResourceHandle::currentStreamPosition const):
(WebCore::ResourceHandle::platformContinueSynchronousDidReceiveResponse):
(WebCore::ResourceHandle::didStartRequest):
(WebCore::ResourceHandle::start):
(WebCore::ResourceHandle::releaseForDownload):
(WebCore::ResourceHandle::sendPendingRequest):
(WebCore::ResourceHandle::cancel):
(WebCore::ResourceHandle::shouldUseCredentialStorage):
(WebCore::ResourceHandle::continueDidReceiveAuthenticationChallenge):
(WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
(WebCore::ResourceHandle::receivedRequestToContinueWithoutCredential):
(WebCore::ResourceHandle::receivedCredential):
(WebCore::ResourceHandle::receivedCancellation):
(WebCore::ResourceHandle::receivedChallengeRejection):
(WebCore::ResourceHandle::platformSetDefersLoading):
(WebCore::sessionFromContext): Deleted.
(WebCore::ResourceHandle::create): Deleted.
(WebCore::ResourceHandle::ResourceHandle): Deleted.
(WebCore::isAuthenticationFailureStatusCode): Deleted.
(WebCore::tlsErrorsChangedCallback): Deleted.
(WebCore::gotHeadersCallback): Deleted.
(WebCore::applyAuthenticationToRequest): Deleted.
(WebCore::restartedCallback): Deleted.
(WebCore::shouldRedirect): Deleted.
(WebCore::shouldRedirectAsGET): Deleted.
(WebCore::continueAfterWillSendRequest): Deleted.
(WebCore::doRedirect): Deleted.
(WebCore::redirectSkipCallback): Deleted.
(WebCore::wroteBodyDataCallback): Deleted.
(WebCore::cleanupSoupRequestOperation): Deleted.
(WebCore::nextMultipartResponsePartCallback): Deleted.
(WebCore::sendRequestCallback): Deleted.
(WebCore::continueAfterDidReceiveResponse): Deleted.
(WebCore::startingCallback): Deleted.
(WebCore::networkEventCallback): Deleted.
(WebCore::createSoupMessageForHandleAndRequest): Deleted.
(WebCore::createSoupRequestAndMessageForHandle): Deleted.
(WebCore::ResourceHandle::timeoutFired): Deleted.
(WebCore::waitingToSendRequest): Deleted.
(WebCore::readCallback): Deleted.

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r230229 r230251  
     12018-04-03  Alex Christensen  <achristensen@webkit.org>
     2
     3        Remove unused libsoup ResourceHandle implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=184048
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        This code is unused since r228901 so let's remove it!
     9
     10        * platform/network/ResourceHandle.h:
     11        * platform/network/ResourceHandleInternal.h:
     12        (WebCore::ResourceHandleInternal::ResourceHandleInternal):
     13        * platform/network/soup/ResourceHandleSoup.cpp:
     14        (WebCore::ResourceHandle::~ResourceHandle):
     15        (WebCore::ResourceHandleInternal::soupSession):
     16        (WebCore::ResourceHandle::cancelledOrClientless):
     17        (WebCore::ResourceHandle::ensureReadBuffer):
     18        (WebCore::ResourceHandle::currentStreamPosition const):
     19        (WebCore::ResourceHandle::platformContinueSynchronousDidReceiveResponse):
     20        (WebCore::ResourceHandle::didStartRequest):
     21        (WebCore::ResourceHandle::start):
     22        (WebCore::ResourceHandle::releaseForDownload):
     23        (WebCore::ResourceHandle::sendPendingRequest):
     24        (WebCore::ResourceHandle::cancel):
     25        (WebCore::ResourceHandle::shouldUseCredentialStorage):
     26        (WebCore::ResourceHandle::continueDidReceiveAuthenticationChallenge):
     27        (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
     28        (WebCore::ResourceHandle::receivedRequestToContinueWithoutCredential):
     29        (WebCore::ResourceHandle::receivedCredential):
     30        (WebCore::ResourceHandle::receivedCancellation):
     31        (WebCore::ResourceHandle::receivedChallengeRejection):
     32        (WebCore::ResourceHandle::platformSetDefersLoading):
     33        (WebCore::sessionFromContext): Deleted.
     34        (WebCore::ResourceHandle::create): Deleted.
     35        (WebCore::ResourceHandle::ResourceHandle): Deleted.
     36        (WebCore::isAuthenticationFailureStatusCode): Deleted.
     37        (WebCore::tlsErrorsChangedCallback): Deleted.
     38        (WebCore::gotHeadersCallback): Deleted.
     39        (WebCore::applyAuthenticationToRequest): Deleted.
     40        (WebCore::restartedCallback): Deleted.
     41        (WebCore::shouldRedirect): Deleted.
     42        (WebCore::shouldRedirectAsGET): Deleted.
     43        (WebCore::continueAfterWillSendRequest): Deleted.
     44        (WebCore::doRedirect): Deleted.
     45        (WebCore::redirectSkipCallback): Deleted.
     46        (WebCore::wroteBodyDataCallback): Deleted.
     47        (WebCore::cleanupSoupRequestOperation): Deleted.
     48        (WebCore::nextMultipartResponsePartCallback): Deleted.
     49        (WebCore::sendRequestCallback): Deleted.
     50        (WebCore::continueAfterDidReceiveResponse): Deleted.
     51        (WebCore::startingCallback): Deleted.
     52        (WebCore::networkEventCallback): Deleted.
     53        (WebCore::createSoupMessageForHandleAndRequest): Deleted.
     54        (WebCore::createSoupRequestAndMessageForHandle): Deleted.
     55        (WebCore::ResourceHandle::timeoutFired): Deleted.
     56        (WebCore::waitingToSendRequest): Deleted.
     57        (WebCore::readCallback): Deleted.
     58
    1592018-04-03  Ross Kirsling  <ross.kirsling@sony.com>
    260
  • trunk/Source/WebCore/platform/network/ResourceHandle.h

    r230019 r230251  
    4141#endif
    4242
    43 #if USE(SOUP)
    44 typedef struct _GTlsCertificate GTlsCertificate;
    45 typedef struct _SoupSession SoupSession;
    46 typedef struct _SoupRequest SoupRequest;
    47 #endif
    48 
    4943#if USE(CF)
    5044typedef const struct __CFData * CFDataRef;
     
    9387class ResourceRequest;
    9488class ResourceResponse;
    95 class SoupNetworkSession;
    9689class SharedBuffer;
    9790class Timer;
     
    10699    WEBCORE_EXPORT static RefPtr<ResourceHandle> create(NetworkingContext*, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff);
    107100    WEBCORE_EXPORT static void loadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data);
    108 
    109 #if USE(SOUP)
    110     static RefPtr<ResourceHandle> create(SoupNetworkSession&, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff);
    111 #endif
    112 
    113101    WEBCORE_EXPORT virtual ~ResourceHandle();
    114102
     
    180168    WEBCORE_EXPORT static void forceContentSniffing();
    181169
    182 #if USE(CURL) || USE(SOUP)
     170#if USE(CURL)
    183171    ResourceHandleInternal* getInternal() { return d.get(); }
    184 #endif
    185 
    186 #if USE(SOUP)
    187     RefPtr<ResourceHandle> releaseForDownload(ResourceHandleClient*);
    188     void continueDidReceiveAuthenticationChallenge(const Credential& credentialFromPersistentStorage);
    189     void sendPendingRequest();
    190     bool cancelledOrClientless();
    191     void ensureReadBuffer();
    192     size_t currentStreamPosition() const;
    193     void didStartRequest();
    194     MonotonicTime m_requestTime;
    195172#endif
    196173
     
    244221    };
    245222
    246 #if USE(SOUP)
    247     ResourceHandle(SoupNetworkSession&, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff);
    248 #endif
    249 
    250223    void platformSetDefersLoading(bool);
    251224
     
    278251#if PLATFORM(COCOA)
    279252    void applySniffingPoliciesAndStoragePartitionIfNeeded(NSURLRequest*&, bool shouldContentSniff, bool shouldContentEncodingSniff);
    280 #endif
    281 
    282 #if USE(SOUP)
    283     void timeoutFired();
    284253#endif
    285254
  • trunk/Source/WebCore/platform/network/ResourceHandleInternal.h

    r230019 r230251  
    4242#endif
    4343
    44 #if USE(SOUP)
    45 #include "GUniquePtrSoup.h"
    46 #include "SoupNetworkSession.h"
    47 #include <libsoup/soup.h>
    48 #include <wtf/RunLoop.h>
    49 #include <wtf/glib/GRefPtr.h>
    50 #endif
    51 
    5244#if PLATFORM(COCOA)
    5345OBJC_CLASS NSURLAuthenticationChallenge;
     
    7971#if USE(CFURLCONNECTION)
    8072        , m_currentRequest(request)
    81 #endif
    82 #if USE(SOUP)
    83         , m_timeoutSource(RunLoop::main(), loader, &ResourceHandle::timeoutFired)
    8473#endif
    8574        , m_failureTimer(*loader, &ResourceHandle::failureTimerFired)
     
    137126#endif
    138127
    139 #if USE(SOUP)
    140     SoupNetworkSession* m_session { nullptr };
    141     GRefPtr<SoupMessage> m_soupMessage;
    142     ResourceResponse m_response;
    143     bool m_cancelled { false };
    144     GRefPtr<SoupRequest> m_soupRequest;
    145     GRefPtr<GInputStream> m_inputStream;
    146     GRefPtr<SoupMultipartInputStream> m_multipartInputStream;
    147     GRefPtr<GCancellable> m_cancellable;
    148     GRefPtr<GAsyncResult> m_deferredResult;
    149     RunLoop::Timer<ResourceHandle> m_timeoutSource;
    150     GUniquePtr<SoupBuffer> m_soupBuffer;
    151     unsigned long m_bodySize { 0 };
    152     unsigned long m_bodyDataSent { 0 };
    153     SoupSession* soupSession();
    154     int m_redirectCount { 0 };
    155     size_t m_previousPosition { 0 };
    156     bool m_useAuthenticationManager { true };
    157     struct {
    158         Credential credential;
    159         ProtectionSpace protectionSpace;
    160     } m_credentialDataToSaveInPersistentStore;
    161 #endif
    162 
    163128#if PLATFORM(COCOA)
    164129    // We need to keep a reference to the original challenge to be able to cancel it.
  • trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp

    r230196 r230251  
    6464namespace WebCore {
    6565
    66 static const size_t gDefaultReadBufferSize = 8192;
    67 
    68 static bool createSoupRequestAndMessageForHandle(ResourceHandle*, const ResourceRequest&);
    69 static void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying = false);
    70 static void sendRequestCallback(GObject*, GAsyncResult*, gpointer);
    71 static void readCallback(GObject*, GAsyncResult*, gpointer);
    72 static void continueAfterDidReceiveResponse(ResourceHandle*);
    73 
    7466ResourceHandleInternal::~ResourceHandleInternal() = default;
    75 
    76 static SoupSession* sessionFromContext(NetworkingContext* context)
    77 {
    78     if (!context || !context->isValid())
    79         return NetworkStorageSession::defaultStorageSession().getOrCreateSoupNetworkSession().soupSession();
    80     return context->storageSession().getOrCreateSoupNetworkSession().soupSession();
    81 }
    8267
    8368ResourceHandle::~ResourceHandle()
    8469{
    85     cleanupSoupRequestOperation(this, true);
    86 }
    87 
    88 SoupSession* ResourceHandleInternal::soupSession()
    89 {
    90     return m_session ? m_session->soupSession() : sessionFromContext(m_context.get());
    91 }
    92 
    93 RefPtr<ResourceHandle> ResourceHandle::create(SoupNetworkSession& session, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff)
    94 {
    95     auto newHandle = adoptRef(*new ResourceHandle(session, request, client, defersLoading, shouldContentSniff, shouldContentEncodingSniff));
    96 
    97     if (newHandle->d->m_scheduledFailureType != NoFailure)
    98         return WTFMove(newHandle);
    99 
    100     if (newHandle->start())
    101         return WTFMove(newHandle);
    102 
    103     return nullptr;
    104 }
    105 
    106 ResourceHandle::ResourceHandle(SoupNetworkSession& session, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff)
    107     : d(std::make_unique<ResourceHandleInternal>(this, nullptr, request, client, defersLoading, shouldContentSniff && shouldContentSniffURL(request.url()), shouldContentEncodingSniff))
    108 {
    109     if (!request.url().isValid()) {
    110         scheduleFailure(InvalidURLFailure);
    111         return;
    112     }
    113 
    114     if (!portAllowed(request.url())) {
    115         scheduleFailure(BlockedFailure);
    116         return;
    117     }
    118 
    119     d->m_session = &session;
    120 }
    121 
    122 bool ResourceHandle::cancelledOrClientless()
    123 {
    124     if (!client())
    125         return true;
    126 
    127     return getInternal()->m_cancelled;
    128 }
    129 
    130 void ResourceHandle::ensureReadBuffer()
    131 {
    132     ResourceHandleInternal* d = getInternal();
    133 
    134     if (d->m_soupBuffer)
    135         return;
    136 
    137 
    138     auto* buffer = static_cast<uint8_t*>(fastMalloc(gDefaultReadBufferSize));
    139     d->m_soupBuffer.reset(soup_buffer_new_with_owner(buffer, gDefaultReadBufferSize, buffer, fastFree));
    140 
    141     ASSERT(d->m_soupBuffer);
    142 }
    143 
    144 static bool isAuthenticationFailureStatusCode(int httpStatusCode)
    145 {
    146     return httpStatusCode == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED || httpStatusCode == SOUP_STATUS_UNAUTHORIZED;
    147 }
    148 
    149 static void tlsErrorsChangedCallback(SoupMessage* message, GParamSpec*, gpointer data)
    150 {
    151     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    152     if (!handle || handle->cancelledOrClientless())
    153         return;
    154 
    155     SoupNetworkSession::checkTLSErrors(handle->getInternal()->m_soupRequest.get(), message, [handle] (const ResourceError& error) {
    156         if (error.isNull())
    157             return;
    158 
    159         handle->client()->didFail(handle.get(), error);
    160         handle->cancel();
    161     });
    162 }
    163 
    164 static void gotHeadersCallback(SoupMessage* message, gpointer data)
    165 {
    166     ResourceHandle* handle = static_cast<ResourceHandle*>(data);
    167     if (!handle || handle->cancelledOrClientless())
    168         return;
    169 
    170     ResourceHandleInternal* d = handle->getInternal();
    171 
    172     if (d->m_context && d->m_context->isValid()) {
    173         // We are a bit more conservative with the persistent credential storage than the session store,
    174         // since we are waiting until we know that this authentication succeeded before actually storing.
    175         // This is because we want to avoid hitting the disk twice (once to add and once to remove) for
    176         // incorrect credentials or polluting the keychain with invalid credentials.
    177         if (!isAuthenticationFailureStatusCode(message->status_code) && message->status_code < 500) {
    178             d->m_context->storageSession().saveCredentialToPersistentStorage(
    179                 d->m_credentialDataToSaveInPersistentStore.protectionSpace,
    180                 d->m_credentialDataToSaveInPersistentStore.credential);
    181         }
    182     }
    183 
    184     // The original response will be needed later to feed to willSendRequest in
    185     // doRedirect() in case we are redirected. For this reason, we store it here.
    186     d->m_response.updateFromSoupMessage(message);
    187 }
    188 
    189 static void applyAuthenticationToRequest(ResourceHandle* handle, ResourceRequest& request, bool redirect)
    190 {
    191     // m_user/m_pass are credentials given manually, for instance, by the arguments passed to XMLHttpRequest.open().
    192     ResourceHandleInternal* d = handle->getInternal();
    193 
    194     String partition = request.cachePartition();
    195 
    196     if (handle->shouldUseCredentialStorage()) {
    197         if (d->m_user.isEmpty() && d->m_pass.isEmpty())
    198             d->m_initialCredential = CredentialStorage::defaultCredentialStorage().get(partition, request.url());
    199         else if (!redirect) {
    200             // If there is already a protection space known for the URL, update stored credentials
    201             // before sending a request. This makes it possible to implement logout by sending an
    202             // XMLHttpRequest with known incorrect credentials, and aborting it immediately (so that
    203             // an authentication dialog doesn't pop up).
    204             CredentialStorage::defaultCredentialStorage().set(partition, Credential(d->m_user, d->m_pass, CredentialPersistenceNone), request.url());
    205         }
    206     }
    207 
    208     String user = d->m_user;
    209     String password = d->m_pass;
    210     if (!d->m_initialCredential.isEmpty()) {
    211         user = d->m_initialCredential.user();
    212         password = d->m_initialCredential.password();
    213     }
    214 
    215     if (user.isEmpty() && password.isEmpty()) {
    216         // In case credential is not available from the handle and credential storage should not to be used,
    217         // disable authentication manager so that credentials stored in libsoup are not used.
    218         d->m_useAuthenticationManager = handle->shouldUseCredentialStorage();
    219         return;
    220     }
    221 
    222     // We always put the credentials into the URL. In the CFNetwork-port HTTP family credentials are applied in
    223     // the didReceiveAuthenticationChallenge callback, but libsoup requires us to use this method to override
    224     // any previously remembered credentials. It has its own per-session credential storage.
    225     URL urlWithCredentials(request.url());
    226     urlWithCredentials.setUser(user);
    227     urlWithCredentials.setPass(password);
    228     request.setURL(urlWithCredentials);
    229 }
    230 
    231 // Called each time the message is going to be sent again except the first time.
    232 // This happens when libsoup handles HTTP authentication.
    233 static void restartedCallback(SoupMessage*, gpointer data)
    234 {
    235     ResourceHandle* handle = static_cast<ResourceHandle*>(data);
    236     if (!handle || handle->cancelledOrClientless())
    237         return;
    238 
    239     handle->m_requestTime = MonotonicTime::now();
    240 }
    241 
    242 static bool shouldRedirect(ResourceHandle* handle)
    243 {
    244     ResourceHandleInternal* d = handle->getInternal();
    245     SoupMessage* message = d->m_soupMessage.get();
    246 
    247     // Some 3xx status codes aren't actually redirects.
    248     if (message->status_code == 300 || message->status_code == 304 || message->status_code == 305 || message->status_code == 306)
    249         return false;
    250 
    251     if (!soup_message_headers_get_one(message->response_headers, "Location"))
    252         return false;
    253 
    254     return true;
    255 }
    256 
    257 static bool shouldRedirectAsGET(SoupMessage* message, URL& newURL, bool crossOrigin)
    258 {
    259     if (message->method == SOUP_METHOD_GET || message->method == SOUP_METHOD_HEAD)
    260         return false;
    261 
    262     if (!newURL.protocolIsInHTTPFamily())
    263         return true;
    264 
    265     switch (message->status_code) {
    266     case SOUP_STATUS_SEE_OTHER:
    267         return true;
    268     case SOUP_STATUS_FOUND:
    269     case SOUP_STATUS_MOVED_PERMANENTLY:
    270         if (message->method == SOUP_METHOD_POST)
    271             return true;
    272         break;
    273     }
    274 
    275     if (crossOrigin && message->method == SOUP_METHOD_DELETE)
    276         return true;
    277 
    278     return false;
    279 }
    280 
    281 static void continueAfterWillSendRequest(ResourceHandle* handle, ResourceRequest&& request)
    282 {
    283     // willSendRequest might cancel the load.
    284     if (handle->cancelledOrClientless())
    285         return;
    286 
    287     ResourceHandleInternal* d = handle->getInternal();
    288     if (protocolHostAndPortAreEqual(request.url(), d->m_response.url()))
    289         applyAuthenticationToRequest(handle, request, true);
    290 
    291     if (!createSoupRequestAndMessageForHandle(handle, request)) {
    292         d->client()->cannotShowURL(handle);
    293         return;
    294     }
    295 
    296     handle->sendPendingRequest();
    297 }
    298 
    299 static void doRedirect(ResourceHandle* handle)
    300 {
    301     ResourceHandleInternal* d = handle->getInternal();
    302     static const int maxRedirects = 20;
    303 
    304     if (d->m_redirectCount++ > maxRedirects) {
    305         d->client()->didFail(handle, ResourceError::transportError(d->m_soupRequest.get(), SOUP_STATUS_TOO_MANY_REDIRECTS, "Too many redirects"));
    306         cleanupSoupRequestOperation(handle);
    307         return;
    308     }
    309 
    310     ResourceRequest newRequest = handle->firstRequest();
    311     SoupMessage* message = d->m_soupMessage.get();
    312     const char* location = soup_message_headers_get_one(message->response_headers, "Location");
    313     URL newURL = URL(URL(soup_message_get_uri(message)), location);
    314     bool crossOrigin = !protocolHostAndPortAreEqual(handle->firstRequest().url(), newURL);
    315     newRequest.setURL(newURL);
    316 
    317     if (newRequest.httpMethod() != "GET") {
    318         // Change newRequest method to GET if change was made during a previous redirection
    319         // or if current redirection says so
    320         if (message->method == SOUP_METHOD_GET || shouldRedirectAsGET(message, newURL, crossOrigin)) {
    321             newRequest.setHTTPMethod("GET");
    322             newRequest.setHTTPBody(nullptr);
    323             newRequest.clearHTTPContentType();
    324         }
    325     }
    326 
    327     // Should not set Referer after a redirect from a secure resource to non-secure one.
    328     if (!newURL.protocolIs("https") && protocolIs(newRequest.httpReferrer(), "https") && handle->context()->shouldClearReferrerOnHTTPSToHTTPRedirect())
    329         newRequest.clearHTTPReferrer();
    330 
    331     d->m_user = newURL.user();
    332     d->m_pass = newURL.pass();
    333     newRequest.removeCredentials();
    334 
    335     if (crossOrigin) {
    336         // If the network layer carries over authentication headers from the original request
    337         // in a cross-origin redirect, we want to clear those headers here.
    338         newRequest.clearHTTPAuthorization();
    339         newRequest.clearHTTPOrigin();
    340 
    341         // TODO: We are losing any username and password specified in the redirect URL, as this is the
    342         // same behavior as the CFNet port. We should investigate if this is really what we want.
    343     }
    344 
    345     cleanupSoupRequestOperation(handle);
    346 
    347     ResourceResponse responseCopy = d->m_response;
    348     d->client()->willSendRequestAsync(handle, WTFMove(newRequest), WTFMove(responseCopy), [handle = makeRef(*handle)] (ResourceRequest&& request) {
    349         continueAfterWillSendRequest(handle.ptr(), WTFMove(request));
    350     });
    351 }
    352 
    353 static void redirectSkipCallback(GObject*, GAsyncResult* asyncResult, gpointer data)
    354 {
    355     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    356 
    357     if (handle->cancelledOrClientless()) {
    358         cleanupSoupRequestOperation(handle.get());
    359         return;
    360     }
    361 
    362     GUniqueOutPtr<GError> error;
    363     ResourceHandleInternal* d = handle->getInternal();
    364     gssize bytesSkipped = g_input_stream_skip_finish(d->m_inputStream.get(), asyncResult, &error.outPtr());
    365     if (error) {
    366         handle->client()->didFail(handle.get(), ResourceError::genericGError(error.get(), d->m_soupRequest.get()));
    367         cleanupSoupRequestOperation(handle.get());
    368         return;
    369     }
    370 
    371     if (bytesSkipped > 0) {
    372         g_input_stream_skip_async(d->m_inputStream.get(), gDefaultReadBufferSize, RunLoopSourcePriority::AsyncIONetwork,
    373             d->m_cancellable.get(), redirectSkipCallback, handle.get());
    374         return;
    375     }
    376 
    377     g_input_stream_close(d->m_inputStream.get(), 0, 0);
    378     doRedirect(handle.get());
    379 }
    380 
    381 static void wroteBodyDataCallback(SoupMessage*, SoupBuffer* buffer, gpointer data)
    382 {
    383     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    384     if (!handle)
    385         return;
    386 
    387     ASSERT(buffer);
    388     ResourceHandleInternal* d = handle->getInternal();
    389     d->m_bodyDataSent += buffer->length;
    390 
    391     if (handle->cancelledOrClientless())
    392         return;
    393 
    394     handle->client()->didSendData(handle.get(), d->m_bodyDataSent, d->m_bodySize);
    395 }
    396 
    397 static void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroying)
    398 {
    399     ResourceHandleInternal* d = handle->getInternal();
    400 
    401     d->m_soupRequest.clear();
    402     d->m_inputStream.clear();
    403     d->m_multipartInputStream.clear();
    404     d->m_cancellable.clear();
    405     d->m_soupBuffer.reset();
    406 
    407     if (d->m_soupMessage) {
    408         g_signal_handlers_disconnect_matched(d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA,
    409                                              0, 0, 0, 0, handle);
    410         g_object_set_data(G_OBJECT(d->m_soupMessage.get()), "handle", 0);
    411         d->m_soupMessage.clear();
    412     }
    413 
    414     d->m_timeoutSource.stop();
    415 
    416     if (!isDestroying)
    417         handle->deref();
    418 }
    419 
    420 size_t ResourceHandle::currentStreamPosition() const
    421 {
    422     GInputStream* baseStream = d->m_inputStream.get();
    423     while (!G_IS_SEEKABLE(baseStream) && G_IS_FILTER_INPUT_STREAM(baseStream))
    424         baseStream = g_filter_input_stream_get_base_stream(G_FILTER_INPUT_STREAM(baseStream));
    425 
    426     if (!G_IS_SEEKABLE(baseStream))
    427         return 0;
    428 
    429     return g_seekable_tell(G_SEEKABLE(baseStream));
    430 }
    431 
    432 static void nextMultipartResponsePartCallback(GObject* /*source*/, GAsyncResult* result, gpointer data)
    433 {
    434     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    435 
    436     if (handle->cancelledOrClientless()) {
    437         cleanupSoupRequestOperation(handle.get());
    438         return;
    439     }
    440 
    441     ResourceHandleInternal* d = handle->getInternal();
    442     ASSERT(!d->m_inputStream);
    443 
    444     GUniqueOutPtr<GError> error;
    445     d->m_inputStream = adoptGRef(soup_multipart_input_stream_next_part_finish(d->m_multipartInputStream.get(), result, &error.outPtr()));
    446 
    447     if (error) {
    448         handle->client()->didFail(handle.get(), ResourceError::httpError(d->m_soupMessage.get(), error.get(), d->m_soupRequest.get()));
    449         cleanupSoupRequestOperation(handle.get());
    450         return;
    451     }
    452 
    453     if (!d->m_inputStream) {
    454         handle->client()->didFinishLoading(handle.get());
    455         cleanupSoupRequestOperation(handle.get());
    456         return;
    457     }
    458 
    459     d->m_response = ResourceResponse();
    460     d->m_response.setURL(handle->firstRequest().url());
    461     d->m_response.updateFromSoupMessageHeaders(soup_multipart_input_stream_get_headers(d->m_multipartInputStream.get()));
    462 
    463     d->m_previousPosition = 0;
    464 
    465     handle->didReceiveResponse(ResourceResponse(d->m_response), [handle = makeRef(*handle)] {
    466         continueAfterDidReceiveResponse(handle.ptr());
    467     });
    468 }
    469 
    470 static void sendRequestCallback(GObject*, GAsyncResult* result, gpointer data)
    471 {
    472     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    473 
    474     if (handle->cancelledOrClientless()) {
    475         cleanupSoupRequestOperation(handle.get());
    476         return;
    477     }
    478 
    479     ResourceHandleInternal* d = handle->getInternal();
    480     SoupMessage* soupMessage = d->m_soupMessage.get();
    481 
    482 
    483     if (d->m_defersLoading) {
    484         d->m_deferredResult = result;
    485         return;
    486     }
    487 
    488     GUniqueOutPtr<GError> error;
    489     GRefPtr<GInputStream> inputStream = adoptGRef(soup_request_send_finish(d->m_soupRequest.get(), result, &error.outPtr()));
    490     if (error) {
    491         handle->client()->didFail(handle.get(), ResourceError::httpError(soupMessage, error.get(), d->m_soupRequest.get()));
    492         cleanupSoupRequestOperation(handle.get());
    493         return;
    494     }
    495 
    496     if (soupMessage) {
    497         if (handle->shouldContentSniff() && soupMessage->status_code != SOUP_STATUS_NOT_MODIFIED) {
    498             const char* sniffedType = soup_request_get_content_type(d->m_soupRequest.get());
    499             d->m_response.setSniffedContentType(sniffedType);
    500         }
    501         d->m_response.updateFromSoupMessage(soupMessage);
    502 
    503         if (SOUP_STATUS_IS_REDIRECTION(soupMessage->status_code) && shouldRedirect(handle.get())) {
    504             d->m_inputStream = inputStream;
    505             g_input_stream_skip_async(d->m_inputStream.get(), gDefaultReadBufferSize, RunLoopSourcePriority::AsyncIONetwork,
    506                 d->m_cancellable.get(), redirectSkipCallback, handle.get());
    507             return;
    508         }
    509     } else {
    510         d->m_response.setURL(handle->firstRequest().url());
    511         const gchar* contentType = soup_request_get_content_type(d->m_soupRequest.get());
    512         d->m_response.setMimeType(extractMIMETypeFromMediaType(contentType));
    513         d->m_response.setTextEncodingName(extractCharsetFromMediaType(contentType));
    514         d->m_response.setExpectedContentLength(soup_request_get_content_length(d->m_soupRequest.get()));
    515     }
    516 
    517     d->m_response.deprecatedNetworkLoadMetrics().responseStart = MonotonicTime::now() - handle->m_requestTime;
    518 
    519     if (soupMessage && d->m_response.isMultipart())
    520         d->m_multipartInputStream = adoptGRef(soup_multipart_input_stream_new(soupMessage, inputStream.get()));
    521     else
    522         d->m_inputStream = inputStream;
    523 
    524     handle->didReceiveResponse(ResourceResponse(d->m_response), [handle = makeRef(*handle)] {
    525         continueAfterDidReceiveResponse(handle.ptr());
    526     });
     70    ASSERT_NOT_REACHED();
    52771}
    52872
    52973void ResourceHandle::platformContinueSynchronousDidReceiveResponse()
    53074{
    531     continueAfterDidReceiveResponse(this);
    532 }
    533 
    534 static void continueAfterDidReceiveResponse(ResourceHandle* handle)
    535 {
    536     if (handle->cancelledOrClientless()) {
    537         cleanupSoupRequestOperation(handle);
    538         return;
    539     }
    540 
    541     ResourceHandleInternal* d = handle->getInternal();
    542     if (d->m_soupMessage && d->m_multipartInputStream && !d->m_inputStream) {
    543         soup_multipart_input_stream_next_part_async(d->m_multipartInputStream.get(), RunLoopSourcePriority::AsyncIONetwork,
    544             d->m_cancellable.get(), nextMultipartResponsePartCallback, handle);
    545         return;
    546     }
    547 
    548     ASSERT(d->m_inputStream);
    549     handle->ensureReadBuffer();
    550     g_input_stream_read_async(d->m_inputStream.get(), const_cast<char*>(d->m_soupBuffer->data), d->m_soupBuffer->length,
    551         RunLoopSourcePriority::AsyncIONetwork, d->m_cancellable.get(), readCallback, handle);
    552 }
    553 
    554 void ResourceHandle::didStartRequest()
    555 {
    556     getInternal()->m_response.deprecatedNetworkLoadMetrics().requestStart = MonotonicTime::now() - m_requestTime;
    557 }
    558 
    559 #if SOUP_CHECK_VERSION(2, 49, 91)
    560 static void startingCallback(SoupMessage*, ResourceHandle* handle)
    561 {
    562     handle->didStartRequest();
    563 }
    564 #endif // SOUP_CHECK_VERSION(2, 49, 91)
    565 
    566 static void networkEventCallback(SoupMessage*, GSocketClientEvent event, GIOStream*, gpointer data)
    567 {
    568     ResourceHandle* handle = static_cast<ResourceHandle*>(data);
    569     if (!handle)
    570         return;
    571 
    572     if (handle->cancelledOrClientless())
    573         return;
    574 
    575     ResourceHandleInternal* d = handle->getInternal();
    576     Seconds deltaTime = MonotonicTime::now() - handle->m_requestTime;
    577     switch (event) {
    578     case G_SOCKET_CLIENT_RESOLVING:
    579         d->m_response.deprecatedNetworkLoadMetrics().domainLookupStart = deltaTime;
    580         break;
    581     case G_SOCKET_CLIENT_RESOLVED:
    582         d->m_response.deprecatedNetworkLoadMetrics().domainLookupEnd = deltaTime;
    583         break;
    584     case G_SOCKET_CLIENT_CONNECTING:
    585         d->m_response.deprecatedNetworkLoadMetrics().connectStart = deltaTime;
    586         if (d->m_response.deprecatedNetworkLoadMetrics().domainLookupStart != Seconds(-1)) {
    587             // WebCore/inspector/front-end/RequestTimingView.js assumes
    588             // that DNS time is included in connection time so must
    589             // substract here the DNS delta that will be added later (see
    590             // WebInspector.RequestTimingView.createTimingTable in the
    591             // file above for more details).
    592             d->m_response.deprecatedNetworkLoadMetrics().connectStart -=
    593                 d->m_response.deprecatedNetworkLoadMetrics().domainLookupEnd - d->m_response.deprecatedNetworkLoadMetrics().domainLookupStart;
    594         }
    595         break;
    596     case G_SOCKET_CLIENT_CONNECTED:
    597         // Web Timing considers that connection time involves dns, proxy & TLS negotiation...
    598         // so we better pick G_SOCKET_CLIENT_COMPLETE for connectEnd
    599         break;
    600     case G_SOCKET_CLIENT_PROXY_NEGOTIATING:
    601         break;
    602     case G_SOCKET_CLIENT_PROXY_NEGOTIATED:
    603         break;
    604     case G_SOCKET_CLIENT_TLS_HANDSHAKING:
    605         d->m_response.deprecatedNetworkLoadMetrics().secureConnectionStart = deltaTime;
    606         break;
    607     case G_SOCKET_CLIENT_TLS_HANDSHAKED:
    608         break;
    609     case G_SOCKET_CLIENT_COMPLETE:
    610         d->m_response.deprecatedNetworkLoadMetrics().connectEnd = deltaTime;
    611         break;
    612     default:
    613         ASSERT_NOT_REACHED();
    614         break;
    615     }
    616 }
    617 
    618 static bool createSoupMessageForHandleAndRequest(ResourceHandle* handle, const ResourceRequest& request)
    619 {
    620     ASSERT(handle);
    621 
    622     ResourceHandleInternal* d = handle->getInternal();
    623     ASSERT(d->m_soupRequest);
    624 
    625     d->m_soupMessage = adoptGRef(soup_request_http_get_message(SOUP_REQUEST_HTTP(d->m_soupRequest.get())));
    626     if (!d->m_soupMessage)
    627         return false;
    628 
    629     SoupMessage* soupMessage = d->m_soupMessage.get();
    630     request.updateSoupMessage(soupMessage);
    631     d->m_bodySize = soupMessage->request_body->length;
    632 
    633     g_object_set_data(G_OBJECT(soupMessage), "handle", handle);
    634     if (!handle->shouldContentSniff())
    635         soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER);
    636     if (!d->m_useAuthenticationManager)
    637         soup_message_disable_feature(soupMessage, SOUP_TYPE_AUTH_MANAGER);
    638 
    639     // Make sure we have an Accept header for subresources; some sites
    640     // want this to serve some of their subresources
    641     if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept"))
    642         soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
    643 
    644     // In the case of XHR .send() and .send("") explicitly tell libsoup to send a zero content-lenght header
    645     // for consistency with other backends (e.g. Chromium's) and other UA implementations like FF. It's done
    646     // in the backend here instead of in XHR code since in XHR CORS checking prevents us from this kind of
    647     // late header manipulation.
    648     if ((request.httpMethod() == "POST" || request.httpMethod() == "PUT") && !d->m_bodySize)
    649         soup_message_headers_set_content_length(soupMessage->request_headers, 0);
    650 
    651     g_signal_connect(d->m_soupMessage.get(), "notify::tls-errors", G_CALLBACK(tlsErrorsChangedCallback), handle);
    652     g_signal_connect(d->m_soupMessage.get(), "got-headers", G_CALLBACK(gotHeadersCallback), handle);
    653     g_signal_connect(d->m_soupMessage.get(), "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), handle);
    654 
    655     unsigned flags = SOUP_MESSAGE_NO_REDIRECT;
    656     soup_message_set_flags(d->m_soupMessage.get(), static_cast<SoupMessageFlags>(soup_message_get_flags(d->m_soupMessage.get()) | flags));
    657 
    658 #if SOUP_CHECK_VERSION(2, 49, 91)
    659     g_signal_connect(d->m_soupMessage.get(), "starting", G_CALLBACK(startingCallback), handle);
    660 #endif
    661     g_signal_connect(d->m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), handle);
    662     g_signal_connect(d->m_soupMessage.get(), "restarted", G_CALLBACK(restartedCallback), handle);
    663 
    664 #if SOUP_CHECK_VERSION(2, 43, 1)
    665     soup_message_set_priority(d->m_soupMessage.get(), toSoupMessagePriority(request.priority()));
    666 #endif
    667 
    668     return true;
    669 }
    670 
    671 static bool createSoupRequestAndMessageForHandle(ResourceHandle* handle, const ResourceRequest& request)
    672 {
    673     ResourceHandleInternal* d = handle->getInternal();
    674 
    675     GUniquePtr<SoupURI> soupURI = request.createSoupURI();
    676     if (!soupURI)
    677         return false;
    678 
    679     GUniqueOutPtr<GError> error;
    680     d->m_soupRequest = adoptGRef(soup_session_request_uri(d->soupSession(), soupURI.get(), &error.outPtr()));
    681     if (error) {
    682         d->m_soupRequest.clear();
    683         return false;
    684     }
    685 
    686     // SoupMessages are only applicable to HTTP-family requests.
    687     if (request.url().protocolIsInHTTPFamily() && !createSoupMessageForHandleAndRequest(handle, request)) {
    688         d->m_soupRequest.clear();
    689         return false;
    690     }
    691 
    692     request.updateSoupRequest(d->m_soupRequest.get());
    693 
    694     return true;
     75    ASSERT_NOT_REACHED();
    69576}
    69677
    69778bool ResourceHandle::start()
    69879{
    699     ASSERT(!d->m_soupMessage);
    700 
    701     // The frame could be null if the ResourceHandle is not associated to any
    702     // Frame, e.g. if we are downloading a file.
    703     // If the frame is not null but the page is null this must be an attempted
    704     // load from an unload handler, so let's just block it.
    705     // If both the frame and the page are not null the context is valid.
    706     if (d->m_context && !d->m_context->isValid())
    707         return false;
    708 
    709     // Only allow the POST and GET methods for non-HTTP requests.
    710     const ResourceRequest& request = firstRequest();
    711     if (!request.url().protocolIsInHTTPFamily() && request.httpMethod() != "GET" && request.httpMethod() != "POST") {
    712         this->scheduleFailure(InvalidURLFailure); // Error must not be reported immediately
    713         return true;
    714     }
    715 
    716     applyAuthenticationToRequest(this, firstRequest(), false);
    717 
    718     if (!createSoupRequestAndMessageForHandle(this, request)) {
    719         this->scheduleFailure(InvalidURLFailure); // Error must not be reported immediately
    720         return true;
    721     }
    722 
    723     // Send the request only if it's not been explicitly deferred.
    724     if (!d->m_defersLoading)
    725         sendPendingRequest();
    726 
    727     return true;
    728 }
    729 
    730 RefPtr<ResourceHandle> ResourceHandle::releaseForDownload(ResourceHandleClient* downloadClient)
    731 {
    732     // We don't adopt the ref, as it will be released by cleanupSoupRequestOperation, which should always run.
    733     ResourceHandle* newHandle = new ResourceHandle(d->m_context.get(), firstRequest(), nullptr, d->m_defersLoading, d->m_shouldContentSniff, d->m_shouldContentEncodingSniff);
    734     newHandle->relaxAdoptionRequirement();
    735     std::swap(d, newHandle->d);
    736 
    737     g_signal_handlers_disconnect_matched(newHandle->d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
    738     g_object_set_data(G_OBJECT(newHandle->d->m_soupMessage.get()), "handle", newHandle);
    739 
    740     newHandle->d->m_client = downloadClient;
    741     continueAfterDidReceiveResponse(newHandle);
    742 
    743     return newHandle;
    744 }
    745 
    746 void ResourceHandle::timeoutFired()
    747 {
    748     client()->didFail(this, ResourceError::timeoutError(firstRequest().url()));
    749     cancel();
    750 }
    751 
    752 void ResourceHandle::sendPendingRequest()
    753 {
    754     m_requestTime = MonotonicTime::now();
    755 
    756     if (d->m_firstRequest.timeoutInterval() > 0)
    757         d->m_timeoutSource.startOneShot(1_s * d->m_firstRequest.timeoutInterval());
    758 
    759     // Balanced by a deref() in cleanupSoupRequestOperation, which should always run.
    760     ref();
    761 
    762     d->m_cancellable = adoptGRef(g_cancellable_new());
    763     soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, this);
     80    ASSERT_NOT_REACHED();
     81    return false;
    76482}
    76583
    76684void ResourceHandle::cancel()
    76785{
    768     d->m_cancelled = true;
    769     if (d->m_soupMessage)
    770         soup_session_cancel_message(d->soupSession(), d->m_soupMessage.get(), SOUP_STATUS_CANCELLED);
    771     else if (d->m_cancellable)
    772         g_cancellable_cancel(d->m_cancellable.get());
     86    ASSERT_NOT_REACHED();
    77387}
    77488
    77589bool ResourceHandle::shouldUseCredentialStorage()
    77690{
    777     return (!client() || client()->shouldUseCredentialStorage(this)) && firstRequest().url().protocolIsInHTTPFamily();
     91    ASSERT_NOT_REACHED();
     92    return false;
    77893}
    77994
    780 void ResourceHandle::continueDidReceiveAuthenticationChallenge(const Credential& credentialFromPersistentStorage)
     95void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
    78196{
    782     ASSERT(!d->m_currentWebChallenge.isNull());
    783     AuthenticationChallenge& challenge = d->m_currentWebChallenge;
    784 
    785     ASSERT(d->m_soupMessage);
    786     if (!credentialFromPersistentStorage.isEmpty())
    787         challenge.setProposedCredential(credentialFromPersistentStorage);
    788 
    789     if (!client()) {
    790         soup_session_unpause_message(d->soupSession(), d->m_soupMessage.get());
    791         clearAuthentication();
    792         return;
    793     }
    794 
    795     client()->didReceiveAuthenticationChallenge(this, challenge);
     97    ASSERT_NOT_REACHED();
    79698}
    79799
    798 void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge)
     100void ResourceHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
    799101{
    800     ASSERT(d->m_currentWebChallenge.isNull());
    801 
    802     String partition = firstRequest().cachePartition();
    803 
    804     // FIXME: Per the specification, the user shouldn't be asked for credentials if there were incorrect ones provided explicitly.
    805     bool useCredentialStorage = shouldUseCredentialStorage();
    806     if (useCredentialStorage) {
    807         if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) {
    808             // The stored credential wasn't accepted, stop using it. There is a race condition
    809             // here, since a different credential might have already been stored by another
    810             // ResourceHandle, but the observable effect should be very minor, if any.
    811             CredentialStorage::defaultCredentialStorage().remove(partition, challenge.protectionSpace());
    812         }
    813 
    814         if (!challenge.previousFailureCount()) {
    815             Credential credential = CredentialStorage::defaultCredentialStorage().get(partition, challenge.protectionSpace());
    816             if (!credential.isEmpty() && credential != d->m_initialCredential) {
    817                 ASSERT(credential.persistence() == CredentialPersistenceNone);
    818 
    819                 // Store the credential back, possibly adding it as a default for this directory.
    820                 if (isAuthenticationFailureStatusCode(challenge.failureResponse().httpStatusCode()))
    821                     CredentialStorage::defaultCredentialStorage().set(partition, credential, challenge.protectionSpace(), challenge.failureResponse().url());
    822 
    823                 soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data());
    824                 return;
    825             }
    826         }
    827     }
    828 
    829     d->m_currentWebChallenge = challenge;
    830     soup_session_pause_message(d->soupSession(), d->m_soupMessage.get());
    831 
    832     // We could also do this before we even start the request, but that would be at the expense
    833     // of all request latency, versus a one-time latency for the small subset of requests that
    834     // use HTTP authentication. In the end, this doesn't matter much, because persistent credentials
    835     // will become session credentials after the first use.
    836     if (useCredentialStorage && d->m_context && d->m_context->isValid()) {
    837         d->m_context->storageSession().getCredentialFromPersistentStorage(challenge.protectionSpace(), d->m_cancellable.get(), [this, protectedThis = makeRef(*this)] (Credential&& credential) {
    838             continueDidReceiveAuthenticationChallenge(WTFMove(credential));
    839         });
    840         return;
    841     }
    842 
    843     continueDidReceiveAuthenticationChallenge(Credential());
     102    ASSERT_NOT_REACHED();
    844103}
    845104
    846 void ResourceHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& challenge)
     105void ResourceHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
    847106{
    848     ASSERT(!challenge.isNull());
    849     if (challenge != d->m_currentWebChallenge)
    850         return;
    851     soup_session_unpause_message(d->soupSession(), d->m_soupMessage.get());
    852 
    853     clearAuthentication();
     107    ASSERT_NOT_REACHED();
    854108}
    855109
    856 void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential)
     110void ResourceHandle::receivedCancellation(const AuthenticationChallenge&)
    857111{
    858     ASSERT(!challenge.isNull());
    859     if (challenge != d->m_currentWebChallenge)
    860         return;
    861 
    862     // FIXME: Support empty credentials. Currently, an empty credential cannot be stored in WebCore credential storage, as that's empty value for its map.
    863     if (credential.isEmpty()) {
    864         receivedRequestToContinueWithoutCredential(challenge);
    865         return;
    866     }
    867 
    868     String partition = firstRequest().cachePartition();
    869 
    870     if (shouldUseCredentialStorage()) {
    871         // Eventually we will manage per-session credentials only internally or use some newly-exposed API from libsoup,
    872         // because once we authenticate via libsoup, there is no way to ignore it for a particular request. Right now,
    873         // we place the credentials in the store even though libsoup will never fire the authenticate signal again for
    874         // this protection space.
    875         if (credential.persistence() == CredentialPersistenceForSession || credential.persistence() == CredentialPersistencePermanent)
    876             CredentialStorage::defaultCredentialStorage().set(partition, credential, challenge.protectionSpace(), challenge.failureResponse().url());
    877 
    878         if (credential.persistence() == CredentialPersistencePermanent) {
    879             d->m_credentialDataToSaveInPersistentStore.credential = credential;
    880             d->m_credentialDataToSaveInPersistentStore.protectionSpace = challenge.protectionSpace();
    881         }
    882     }
    883 
    884     ASSERT(d->m_soupMessage);
    885     soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data());
    886     soup_session_unpause_message(d->soupSession(), d->m_soupMessage.get());
    887 
    888     clearAuthentication();
    889 }
    890 
    891 void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challenge)
    892 {
    893     ASSERT(!challenge.isNull());
    894     if (challenge != d->m_currentWebChallenge)
    895         return;
    896 
    897     if (cancelledOrClientless()) {
    898         clearAuthentication();
    899         return;
    900     }
    901 
    902     ASSERT(d->m_soupMessage);
    903     soup_session_unpause_message(d->soupSession(), d->m_soupMessage.get());
    904 
    905     if (client())
    906         client()->receivedCancellation(this, challenge);
    907 
    908     clearAuthentication();
     112    ASSERT_NOT_REACHED();
    909113}
    910114
     
    914118}
    915119
    916 void ResourceHandle::receivedChallengeRejection(const AuthenticationChallenge& challenge)
     120void ResourceHandle::receivedChallengeRejection(const AuthenticationChallenge&)
    917121{
    918     // This is only used by layout tests, soup based ports don't implement this.
    919     notImplemented();
    920     receivedRequestToContinueWithoutCredential(challenge);
     122    ASSERT_NOT_REACHED();
    921123}
    922124
    923 static bool waitingToSendRequest(ResourceHandle* handle)
     125void ResourceHandle::platformSetDefersLoading(bool)
    924126{
    925     // We need to check for d->m_soupRequest because the request may have raised a failure
    926     // (for example invalid URLs). We cannot  simply check for d->m_scheduledFailure because
    927     // it's cleared as soon as the failure event is fired.
    928     return handle->getInternal()->m_soupRequest && !handle->getInternal()->m_cancellable;
    929 }
    930 
    931 void ResourceHandle::platformSetDefersLoading(bool defersLoading)
    932 {
    933     if (cancelledOrClientless())
    934         return;
    935 
    936     // Except when canceling a possible timeout timer, we only need to take action here to UN-defer loading.
    937     if (defersLoading) {
    938         d->m_timeoutSource.stop();
    939         return;
    940     }
    941 
    942     if (waitingToSendRequest(this)) {
    943         sendPendingRequest();
    944         return;
    945     }
    946 
    947     if (d->m_deferredResult) {
    948         GRefPtr<GAsyncResult> asyncResult = adoptGRef(d->m_deferredResult.leakRef());
    949 
    950         if (d->m_inputStream)
    951             readCallback(G_OBJECT(d->m_inputStream.get()), asyncResult.get(), this);
    952         else
    953             sendRequestCallback(G_OBJECT(d->m_soupRequest.get()), asyncResult.get(), this);
    954     }
     127    ASSERT_NOT_REACHED();
    955128}
    956129
     
    960133}
    961134
    962 static void readCallback(GObject*, GAsyncResult* asyncResult, gpointer data)
    963 {
    964     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
    965 
    966     if (handle->cancelledOrClientless()) {
    967         cleanupSoupRequestOperation(handle.get());
    968         return;
    969     }
    970 
    971     ResourceHandleInternal* d = handle->getInternal();
    972     if (d->m_defersLoading) {
    973         d->m_deferredResult = asyncResult;
    974         return;
    975     }
    976 
    977     GUniqueOutPtr<GError> error;
    978     gssize bytesRead = g_input_stream_read_finish(d->m_inputStream.get(), asyncResult, &error.outPtr());
    979 
    980     if (error) {
    981         handle->client()->didFail(handle.get(), ResourceError::genericGError(error.get(), d->m_soupRequest.get()));
    982         cleanupSoupRequestOperation(handle.get());
    983         return;
    984     }
    985 
    986     if (!bytesRead) {
    987         // If this is a multipart message, we'll look for another part.
    988         if (d->m_soupMessage && d->m_multipartInputStream) {
    989             d->m_inputStream.clear();
    990             soup_multipart_input_stream_next_part_async(d->m_multipartInputStream.get(), RunLoopSourcePriority::AsyncIONetwork,
    991                 d->m_cancellable.get(), nextMultipartResponsePartCallback, handle.get());
    992             return;
    993         }
    994 
    995         g_input_stream_close(d->m_inputStream.get(), 0, 0);
    996 
    997         handle->client()->didFinishLoading(handle.get());
    998         cleanupSoupRequestOperation(handle.get());
    999         return;
    1000     }
    1001 
    1002     // It's mandatory to have sent a response before sending data
    1003     ASSERT(!d->m_response.isNull());
    1004 
    1005     size_t currentPosition = handle->currentStreamPosition();
    1006     size_t encodedDataLength = currentPosition ? currentPosition - d->m_previousPosition : bytesRead;
    1007 
    1008     ASSERT(d->m_soupBuffer);
    1009     d->m_soupBuffer->length = bytesRead; // The buffer might be larger than the number of bytes read. SharedBuffer looks at the length property.
    1010     handle->client()->didReceiveBuffer(handle.get(), SharedBuffer::wrapSoupBuffer(d->m_soupBuffer.release()), encodedDataLength);
    1011 
    1012     d->m_previousPosition = currentPosition;
    1013 
    1014     // didReceiveBuffer may cancel the load, which may release the last reference.
    1015     if (handle->cancelledOrClientless()) {
    1016         cleanupSoupRequestOperation(handle.get());
    1017         return;
    1018     }
    1019 
    1020     handle->ensureReadBuffer();
    1021     g_input_stream_read_async(d->m_inputStream.get(), const_cast<char*>(d->m_soupBuffer->data), d->m_soupBuffer->length, RunLoopSourcePriority::AsyncIONetwork,
    1022         d->m_cancellable.get(), readCallback, handle.get());
    1023 }
    1024 
    1025135}
    1026136
Note: See TracChangeset for help on using the changeset viewer.