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

Changeset 130699 in webkit


Ignore:
Timestamp:
Oct 8, 2012, 4:12:33 PM (14 years ago)
Author:
Martin Robinson
Message:

[Soup] Simplify the way that requests are started
​https://bugs.webkit.org/show_bug.cgi?id=98532

Reviewed by Gustavo Noronha Silva.

Simplify the creation of the libsoup request and message when kicking off
requests, by elminating a bit of duplicate code.

No new tests. This should not change any behavior.

  • platform/network/ResourceHandle.h:

(ResourceHandle):

  • platform/network/soup/ResourceHandleSoup.cpp:

(WebCore):
(WebCore::ResourceHandleInternal::soupSession): Ensure the session
is initialized when passing it to the caller.
(WebCore::createSoupMessageForHandleAndRequest): Added this helper which
takes care of creating the SoupMessage for HTTP/HTTPS requests.
(WebCore::createSoupRequestAndMessageForHandle): Collapsed the HTTP and
non-HTTP request creation into this helper.
(WebCore::ResourceHandle::start): Call the new helper now and then sendPendingRequest.
(WebCore::ResourceHandle::sendPendingRequest): Instead of having special
helpers to create and send the request, duplicating the logic for sending it
across the file, add this method which can be used in both cases.
(WebCore::waitingToSendRequest): Reworked the hasBeenSent method to answer
the question of whether or not the request is ready to be sent, but is unsent.
(WebCore::ResourceHandle::platformSetDefersLoading): Use the new helper.

  • platform/network/soup/ResourceRequest.h:

(ResourceRequest): Added a new method for getting the URL string for soup.

  • platform/network/soup/ResourceRequestSoup.cpp:

(WebCore::ResourceRequest::urlStringForSoup): Added.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r130698 r130699  
     12012-10-06  Martin Robinson  <mrobinson@igalia.com>
     2
     3        [Soup] Simplify the way that requests are started
     4        https://bugs.webkit.org/show_bug.cgi?id=98532
     5
     6        Reviewed by Gustavo Noronha Silva.
     7
     8        Simplify the creation of the libsoup request and message when kicking off
     9        requests, by elminating a bit of duplicate code.
     10
     11        No new tests. This should not change any behavior.
     12
     13        * platform/network/ResourceHandle.h:
     14        (ResourceHandle):
     15        * platform/network/soup/ResourceHandleSoup.cpp:
     16        (WebCore):
     17        (WebCore::ResourceHandleInternal::soupSession): Ensure the session
     18        is initialized when passing it to the caller.
     19        (WebCore::createSoupMessageForHandleAndRequest): Added this helper which
     20        takes care of creating the SoupMessage for HTTP/HTTPS requests.
     21        (WebCore::createSoupRequestAndMessageForHandle): Collapsed the HTTP and
     22        non-HTTP request creation into this helper.
     23        (WebCore::ResourceHandle::start): Call the new helper now and then sendPendingRequest.
     24        (WebCore::ResourceHandle::sendPendingRequest): Instead of having special
     25        helpers to create and send the request, duplicating the logic for sending it
     26        across the file, add this method which can be used in both cases.
     27        (WebCore::waitingToSendRequest): Reworked the hasBeenSent method to answer
     28        the question of whether or not the request is ready to be sent, but is unsent.
     29        (WebCore::ResourceHandle::platformSetDefersLoading): Use the new helper.
     30        * platform/network/soup/ResourceRequest.h:
     31        (ResourceRequest): Added a new method for getting the URL string for soup.
     32        * platform/network/soup/ResourceRequestSoup.cpp:
     33        (WebCore::ResourceRequest::urlStringForSoup): Added.
     34
    1352012-10-08  Eric Seidel  <eric@webkit.org>
    236
  • trunk/Source/WebCore/platform/network/ResourceHandle.h

    r130259 r130699  
    169169
    170170#if USE(SOUP)
     171    void sendPendingRequest();
    171172    static SoupSession* defaultSession();
    172173    static uint64_t getSoupRequestInitiaingPageID(SoupRequest*);
  • trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp

    r130613 r130699  
    204204static void closeCallback(GObject*, GAsyncResult*, gpointer);
    205205static gboolean requestTimeoutCallback(void*);
    206 static bool startNonHTTPRequest(ResourceHandle*, KURL);
    207206#if ENABLE(WEB_TIMING)
    208207static int  milisecondsSinceRequest(double requestTime);
    … …  
    231230{
    232231    return (context && context->isValid()) ? context->soupSession() : ResourceHandle::defaultSession();
    233 }
    234 
    235 SoupSession* ResourceHandleInternal::soupSession()
    236 {
    237     return sessionFromContext(m_context.get());
    238232}
    239233
    … …  
    276270
    277271    g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef));
     272}
     273
     274SoupSession* ResourceHandleInternal::soupSession()
     275{
     276    SoupSession* session = sessionFromContext(m_context.get());
     277    ensureSessionIsInitialized(session);
     278    return session;
    278279}
    279280
    … …  
    684685}
    685686
    686 static bool startHTTPRequest(ResourceHandle* handle)
     687static bool createSoupMessageForHandleAndRequest(ResourceHandle* handle, const ResourceRequest& request)
    687688{
    688689    ASSERT(handle);
    689 
    690     ResourceHandleInternal* d = handle->getInternal();
    691 
    692     SoupSession* session = d->soupSession();
    693     ensureSessionIsInitialized(session);
    694     SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(session, SOUP_TYPE_REQUESTER));
    695 
    696     ResourceRequest request(handle->firstRequest());
    697     KURL url(request.url());
    698     url.removeFragmentIdentifier();
    699     request.setURL(url);
    700 
    701     GOwnPtr<GError> error;
    702     d->m_soupRequest = adoptGRef(soup_requester_request(requester, url.string().utf8().data(), &error.outPtr()));
    703     if (error) {
    704         d->m_soupRequest = 0;
    705         return false;
    706     }
    707 
    708     setSoupRequestInitiaingPageID(d->m_soupRequest.get(), d->initiatingPageID());
    709 
     690    ASSERT(d->m_soupRequest);
     691
     692    ResourceHandleInternal* d = handle->getInternal();
    710693    d->m_soupMessage = adoptGRef(soup_request_http_get_message(SOUP_REQUEST_HTTP(d->m_soupRequest.get())));
    711694    if (!d->m_soupMessage)
    … …  
    717700    if (!handle->shouldContentSniff())
    718701        soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER);
    719 
    720     g_signal_connect(soupMessage, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
    721     g_signal_connect(soupMessage, "restarted", G_CALLBACK(restartedCallback), handle);
    722     g_signal_connect(soupMessage, "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), handle);
    723 
    724 #if ENABLE(WEB_TIMING)
    725     g_signal_connect(soupMessage, "network-event", G_CALLBACK(networkEventCallback), handle);
    726     g_signal_connect(soupMessage, "wrote-body", G_CALLBACK(wroteBodyCallback), handle);
    727     g_object_set_data(G_OBJECT(soupMessage), "handle", handle);
    728 #endif
    729702
    730703    String firstPartyString = request.firstPartyForCookies().string();
    … …  
    734707    }
    735708
    736     FormData* httpBody = d->m_firstRequest.httpBody();
    737     CString contentType = d->m_firstRequest.httpContentType().utf8().data();
    738     if (httpBody && !httpBody->isEmpty()
    739         && !addFormElementsToSoupMessage(soupMessage, contentType.data(), httpBody, d->m_bodySize)) {
     709    FormData* httpBody = request.httpBody();
     710    CString contentType = request.httpContentType().utf8().data();
     711    if (httpBody && !httpBody->isEmpty() && !addFormElementsToSoupMessage(soupMessage, contentType.data(), httpBody, d->m_bodySize)) {
    740712        // We failed to prepare the body data, so just fail this load.
    741         g_signal_handlers_disconnect_matched(soupMessage, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, handle);
    742713        d->m_soupMessage.clear();
    743714        return false;
    744715    }
    745 
    746     // balanced by a deref() in cleanupSoupRequestOperation, which should always run
    747     handle->ref();
    748 
    749 #if ENABLE(WEB_TIMING)
    750     d->m_response.setResourceLoadTiming(ResourceLoadTiming::create());
    751 #endif
    752716
    753717    // Make sure we have an Accept header for subresources; some sites
    … …  
    756720        soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
    757721
    758     // In the case of XHR .send() and .send("") explicitly tell libsoup
    759     // to send a zero content-lenght header for consistency
    760     // with other backends (e.g. Chromium's) and other UA implementations like FF.
    761     // It's done in the backend here instead of in XHR code since in XHR CORS checking
    762     // prevents us from this kind of late header manipulation.
     722    // In the case of XHR .send() and .send("") explicitly tell libsoup to send a zero content-lenght header
     723    // for consistency with other backends (e.g. Chromium's) and other UA implementations like FF. It's done
     724    // in the backend here instead of in XHR code since in XHR CORS checking prevents us from this kind of
     725    // late header manipulation.
    763726    if ((request.httpMethod() == "POST" || request.httpMethod() == "PUT")
    764727        && (!request.httpBody() || request.httpBody()->isEmpty()))
    765728        soup_message_headers_set_content_length(soupMessage->request_headers, 0);
    766729
    767     // Send the request only if it's not been explicitly deferred.
    768     if (!d->m_defersLoading) {
     730    g_signal_connect(d->m_soupMessage.get(), "got-headers", G_CALLBACK(gotHeadersCallback), handle);
     731    g_signal_connect(d->m_soupMessage.get(), "restarted", G_CALLBACK(restartedCallback), handle);
     732    g_signal_connect(d->m_soupMessage.get(), "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), handle);
     733
    769734#if ENABLE(WEB_TIMING)
    770         d->m_response.resourceLoadTiming()->requestTime = monotonicallyIncreasingTime();
     735    d->m_response.setResourceLoadTiming(ResourceLoadTiming::create());
     736    g_signal_connect(d->m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), handle);
     737    g_signal_connect(d->m_soupMessage.get(), "wrote-body", G_CALLBACK(wroteBodyCallback), handle);
     738    g_object_set_data(G_OBJECT(d->m_soupMessage.get()), "handle", handle);
    771739#endif
    772         if (d->m_firstRequest.timeoutInterval() > 0) {
    773             // soup_add_timeout returns a GSource* whose only reference is owned by the context. We need to have our own reference to it, hence not using adoptRef.
    774             d->m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(), d->m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, handle);
    775         }
    776         d->m_cancellable = adoptGRef(g_cancellable_new());
    777         soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, handle);
     740
     741    return true;
     742}
     743
     744static bool createSoupRequestAndMessageForHandle(ResourceHandle* handle, bool isHTTPFamilyRequest)
     745{
     746    ResourceHandleInternal* d = handle->getInternal();
     747    SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(d->soupSession(), SOUP_TYPE_REQUESTER));
     748
     749    GOwnPtr<GError> error;
     750    const ResourceRequest& request = handle->firstRequest();
     751    d->m_soupRequest = adoptGRef(soup_requester_request(requester, request.urlStringForSoup().utf8().data(), &error.outPtr()));
     752    if (error) {
     753        d->m_soupRequest.clear();
     754        return false;
     755    }
     756
     757    // Non-HTTP family requests do not need a soupMessage, as it's callbacks really only apply to HTTP.
     758    if (isHTTPFamilyRequest && !createSoupMessageForHandleAndRequest(handle, request)) {
     759        d->m_soupRequest.clear();
     760        return false;
    778761    }
    779762
    … …  
    802785    }
    803786
    804     KURL url = firstRequest().url();
    805     String urlString = url.string();
    806     String protocol = url.protocol();
    807 
    808787    // Used to set the authentication dialog toplevel; may be NULL
    809788    d->m_context = context;
    810789
    811     if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) {
    812         if (startHTTPRequest(this))
    813             return true;
    814     }
    815 
    816     if (startNonHTTPRequest(this, url))
     790    // Only allow the POST and GET methods for non-HTTP requests.
     791    const ResourceRequest& request = firstRequest();
     792    bool isHTTPFamilyRequest = request.url().protocolIsInHTTPFamily();
     793    if (!isHTTPFamilyRequest && request.httpMethod() != "GET" && request.httpMethod() != "POST") {
     794        this->scheduleFailure(InvalidURLFailure); // Error must not be reported immediately
    817795        return true;
    818 
    819     // Error must not be reported immediately
    820     this->scheduleFailure(InvalidURLFailure);
     796    }
     797
     798    if (!createSoupRequestAndMessageForHandle(this, isHTTPFamilyRequest)) {
     799        this->scheduleFailure(InvalidURLFailure); // Error must not be reported immediately
     800        return true;
     801    }
     802
     803    setSoupRequestInitiaingPageID(d->m_soupRequest.get(), d->initiatingPageID());
     804
     805    // Send the request only if it's not been explicitly deferred.
     806    if (!d->m_defersLoading)
     807        sendPendingRequest();
    821808
    822809    return true;
     810}
     811
     812void ResourceHandle::sendPendingRequest()
     813{
     814#if ENABLE(WEB_TIMING)
     815    if (d->m_response.resourceLoadTiming())
     816        d->m_response.resourceLoadTiming()->requestTime = monotonicallyIncreasingTime();
     817#endif
     818
     819    if (d->m_firstRequest.timeoutInterval() > 0) {
     820        // soup_add_timeout returns a GSource* whose only reference is owned by
     821        // the context. We need to have our own reference to it, hence not using adoptRef.
     822        d->m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(),
     823            d->m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, this);
     824    }
     825
     826    // Balanced by a deref() in cleanupSoupRequestOperation, which should always run.
     827    ref();
     828
     829    d->m_cancellable = adoptGRef(g_cancellable_new());
     830    soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, this);
    823831}
    824832
    … …  
    847855}
    848856
    849 static bool hasBeenSent(ResourceHandle* handle)
    850 {
    851     ResourceHandleInternal* d = handle->getInternal();
    852 
    853     return d->m_cancellable;
     857static bool waitingToSendRequest(ResourceHandle* handle)
     858{
     859    // We need to check for d->m_soupRequest because the request may have raised a failure
     860    // (for example invalid URLs). We cannot  simply check for d->m_scheduledFailure because
     861    // it's cleared as soon as the failure event is fired.
     862    return handle->getInternal()->m_soupRequest && !handle->getInternal()->m_cancellable;
    854863}
    855864
    … …  
    868877    }
    869878
    870     // We need to check for d->m_soupRequest because the request may
    871     // have raised a failure (for example invalid URLs). We cannot
    872     // simply check for d->m_scheduledFailure because it's cleared as
    873     // soon as the failure event is fired.
    874     if (!hasBeenSent(this) && d->m_soupRequest) {
    875 #if ENABLE(WEB_TIMING)
    876         if (d->m_response.resourceLoadTiming())
    877             d->m_response.resourceLoadTiming()->requestTime = monotonicallyIncreasingTime();
    878 #endif
    879         d->m_cancellable = adoptGRef(g_cancellable_new());
    880         if (d->m_firstRequest.timeoutInterval() > 0) {
    881             // soup_add_timeout returns a GSource* whose only reference is owned by the context. We need to have our own reference to it, hence not using adoptRef.
    882             d->m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(), d->m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, this);
    883         }
    884         soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, this);
     879    if (waitingToSendRequest(this)) {
     880        sendPendingRequest();
    885881        return;
    886882    }
    … …  
    10101006
    10111007    return FALSE;
    1012 }
    1013 
    1014 static bool startNonHTTPRequest(ResourceHandle* handle, KURL url)
    1015 {
    1016     ASSERT(handle);
    1017 
    1018     if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST")
    1019         return false;
    1020 
    1021     ResourceHandleInternal* d = handle->getInternal();
    1022 
    1023     SoupSession* session = d->soupSession();
    1024     ensureSessionIsInitialized(session);
    1025     SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(session, SOUP_TYPE_REQUESTER));
    1026 
    1027     CString urlStr = url.string().utf8();
    1028 
    1029     GOwnPtr<GError> error;
    1030     d->m_soupRequest = adoptGRef(soup_requester_request(requester, urlStr.data(), &error.outPtr()));
    1031     if (error) {
    1032         d->m_soupRequest = 0;
    1033         return false;
    1034     }
    1035 
    1036     // balanced by a deref() in cleanupSoupRequestOperation, which should always run
    1037     handle->ref();
    1038 
    1039     setSoupRequestInitiaingPageID(d->m_soupRequest.get(), d->initiatingPageID());
    1040 
    1041     // Send the request only if it's not been explicitly deferred.
    1042     if (!d->m_defersLoading) {
    1043         d->m_cancellable = adoptGRef(g_cancellable_new());
    1044         if (d->m_firstRequest.timeoutInterval() > 0) {
    1045             // soup_add_timeout returns a GSource* whose only reference is owned by the context. We need to have our own reference to it, hence not using adoptRef.
    1046             d->m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(), d->m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, handle);
    1047         }
    1048         soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, handle);
    1049     }
    1050 
    1051     return true;
    10521008}
    10531009
  • trunk/Source/WebCore/platform/network/soup/ResourceRequest.h

    r95901 r130699  
    7575        void setSoupMessageFlags(SoupMessageFlags soupFlags) { m_soupFlags = soupFlags; }
    7676
     77        String urlStringForSoup() const;
     78
    7779    private:
    7880        friend class ResourceRequestBase;
  • trunk/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp

    r130612 r130699  
    125125}
    126126
     127String ResourceRequest::urlStringForSoup() const
     128{
     129    KURL url = m_url;
     130    url.removeFragmentIdentifier();
     131    return url.string();
    127132}
     133
     134}
Note: See TracChangeset for help on using the changeset viewer.