Changeset 69606 in webkit


Ignore:
Timestamp:
Oct 12, 2010 2:44:43 PM (13 years ago)
Author:
Martin Robinson
Message:

2010-10-12 Sheriff Bot <webkit.review.bot@gmail.com>

Unreviewed, rolling out r69589.
http://trac.webkit.org/changeset/69589
https://bugs.webkit.org/show_bug.cgi?id=47547

Wrong patch landed from a bug with two patches (Requested by
mrobinson on #webkit).

  • platform/network/ResourceHandleInternal.h: (WebCore::ResourceHandleInternal::ResourceHandleInternal):
  • platform/network/soup/ResourceHandleSoup.cpp: (WebCore::ResourceHandleInternal::~ResourceHandleInternal): (WebCore::ResourceHandle::~ResourceHandle): (WebCore::restartedCallback): (WebCore::gotChunkCallback): (WebCore::finishedCallback): (WebCore::parseDataUrl): (WebCore::startHttp):
  • platform/network/soup/ResourceRequest.h:
  • platform/network/soup/ResourceRequestSoup.cpp:

2010-10-12 Sheriff Bot <webkit.review.bot@gmail.com>

Unreviewed, rolling out r69589.
http://trac.webkit.org/changeset/69589
https://bugs.webkit.org/show_bug.cgi?id=47547

Wrong patch landed from a bug with two patches (Requested by
mrobinson on #webkit).

  • webkit/webkitdownload.cpp: (webkit_download_new_with_handle): (webkit_download_start):
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r69603 r69606  
     12010-10-12  Sheriff Bot  <webkit.review.bot@gmail.com>
     2
     3        Unreviewed, rolling out r69589.
     4        http://trac.webkit.org/changeset/69589
     5        https://bugs.webkit.org/show_bug.cgi?id=47547
     6
     7        Wrong patch landed from a bug with two patches (Requested by
     8        mrobinson on #webkit).
     9
     10        * platform/network/ResourceHandleInternal.h:
     11        (WebCore::ResourceHandleInternal::ResourceHandleInternal):
     12        * platform/network/soup/ResourceHandleSoup.cpp:
     13        (WebCore::ResourceHandleInternal::~ResourceHandleInternal):
     14        (WebCore::ResourceHandle::~ResourceHandle):
     15        (WebCore::restartedCallback):
     16        (WebCore::gotChunkCallback):
     17        (WebCore::finishedCallback):
     18        (WebCore::parseDataUrl):
     19        (WebCore::startHttp):
     20        * platform/network/soup/ResourceRequest.h:
     21        * platform/network/soup/ResourceRequestSoup.cpp:
     22
    1232010-10-12  Simon Fraser  <simon.fraser@apple.com>
    224
  • trunk/WebCore/platform/network/ResourceHandleInternal.h

    r69589 r69606  
    4747
    4848#if USE(SOUP)
    49 #include "soup-requester.h"
    50 #include <GRefPtr.h>
    5149#include <libsoup/soup.h>
    5250class Frame;
     
    111109#endif
    112110#if USE(SOUP)
     111            , m_msg(0)
    113112            , m_cancelled(false)
     113            , m_gfile(0)
     114            , m_inputStream(0)
     115            , m_cancellable(0)
    114116            , m_buffer(0)
     117            , m_bufferSize(0)
    115118            , m_total(0)
    116119            , m_idleHandler(0)
    117             , m_gotChunkHandler(0)
    118120#endif
    119121#if PLATFORM(QT)
     
    132134            m_pass = url.pass();
    133135            m_firstRequest.removeCredentials();
    134 #if USE(SOUP)
    135             m_requester = adoptPlatformRef(webkit_soup_requester_new());
    136 #endif
    137136        }
    138137       
     
    187186#endif
    188187#if USE(SOUP)
    189         PlatformRefPtr<SoupMessage> m_soupMessage;
     188        SoupMessage* m_msg;
    190189        ResourceResponse m_response;
    191190        bool m_cancelled;
    192         PlatformRefPtr<WebKitSoupRequest> m_soupRequest;
    193         PlatformRefPtr<WebKitSoupRequester> m_requester;
    194         PlatformRefPtr<GInputStream> m_inputStream;
    195         PlatformRefPtr<GCancellable> m_cancellable;
     191        GFile* m_gfile;
     192        GInputStream* m_inputStream;
     193        GCancellable* m_cancellable;
    196194        char* m_buffer;
    197         gsize m_total;
     195        gsize m_bufferSize, m_total;
    198196        guint m_idleHandler;
    199197        RefPtr<NetworkingContext> m_context;
    200         gulong m_gotChunkHandler;
    201198#endif
    202199#if PLATFORM(QT)
  • trunk/WebCore/platform/network/soup/ResourceHandleSoup.cpp

    r69589 r69606  
    4646#include "ResourceResponse.h"
    4747#include "SharedBuffer.h"
    48 #include "soup-request-http.h"
    4948#include "TextEncoding.h"
     49
    5050#include <errno.h>
    5151#include <fcntl.h>
     
    5959namespace WebCore {
    6060
    61 #define READ_BUFFER_SIZE 8192
    62 
    6361class WebCoreSynchronousLoader : public ResourceHandleClient, public Noncopyable {
    6462public:
     
    123121}
    124122
    125 static void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying);
    126 static void sendRequestCallback(GObject*, GAsyncResult*, gpointer);
    127 static void readCallback(GObject*, GAsyncResult*, gpointer);
    128 static void closeCallback(GObject*, GAsyncResult*, gpointer);
    129 static bool startGio(ResourceHandle*, KURL);
     123static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying);
     124static bool startData(ResourceHandle* handle, String urlString);
     125static bool startGio(ResourceHandle* handle, KURL url);
    130126
    131127ResourceHandleInternal::~ResourceHandleInternal()
    132128{
    133     if (m_soupRequest)
    134         g_object_set_data(G_OBJECT(m_soupRequest.get()), "webkit-resource", 0);
     129    if (m_msg) {
     130        g_object_unref(m_msg);
     131        m_msg = 0;
     132    }
    135133
    136134    if (m_idleHandler) {
     
    142140ResourceHandle::~ResourceHandle()
    143141{
    144     cleanupSoupRequestOperation(this, true);
     142    if (d->m_msg)
     143        g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA,
     144                                             0, 0, 0, 0, this);
     145
     146    cleanupGioOperation(this, true);
    145147}
    146148
     
    184186        return;
    185187
    186     GOwnPtr<char> uri(soup_uri_to_string(soup_message_get_uri(msg), false));
    187     String location = String::fromUTF8(uri.get());
     188    char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
     189    String location = String(uri);
     190    g_free(uri);
    188191    KURL newURL = KURL(handle->firstRequest().url(), location);
    189192
     
    211214    if (!firstPartyString.isEmpty()) {
    212215        GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
    213         soup_message_set_first_party(d->m_soupMessage.get(), firstParty.get());
     216        soup_message_set_first_party(d->m_msg, firstParty.get());
    214217    }
    215218#endif
     
    291294
    292295    client->didReceiveData(handle.get(), chunk->data, chunk->length, false);
    293 
    294 }
    295 
     296}
     297
     298// Called at the end of the message, with all the necessary about the last informations.
     299// Doesn't get called for redirects.
     300static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data)
     301{
     302    RefPtr<ResourceHandle> handle = adoptRef(static_cast<ResourceHandle*>(data));
     303    // TODO: maybe we should run this code even if there's no client?
     304    if (!handle)
     305        return;
     306
     307    ResourceHandleInternal* d = handle->getInternal();
     308
     309    ResourceHandleClient* client = handle->client();
     310    if (!client)
     311        return;
     312
     313    if (d->m_cancelled)
     314        return;
     315
     316    if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
     317        char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
     318        ResourceError error(g_quark_to_string(SOUP_HTTP_ERROR),
     319                            msg->status_code,
     320                            uri,
     321                            String::fromUTF8(msg->reason_phrase));
     322        g_free(uri);
     323        client->didFail(handle.get(), error);
     324        return;
     325    }
     326
     327    if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
     328        fillResponseFromMessage(msg, &d->m_response);
     329        client->didReceiveResponse(handle.get(), d->m_response);
     330
     331        // WebCore might have cancelled the job in the while
     332        if (d->m_cancelled)
     333            return;
     334
     335        if (msg->response_body->data)
     336            client->didReceiveData(handle.get(), msg->response_body->data, msg->response_body->length, true);
     337    }
     338
     339    client->didFinishLoading(handle.get(), 0);
     340}
     341
     342// parseDataUrl() is taken from the CURL http backend.
    296343static gboolean parseDataUrl(gpointer callbackData)
    297344{
     
    318365
    319366    String mediaType = url.substring(5, index - 5);
     367    String data = url.substring(index + 1);
    320368
    321369    bool isBase64 = mediaType.endsWith(";base64", false);
     
    333381    response.setMimeType(mimeType);
    334382
    335     // For non base64 encoded data we have to convert to UTF-16 early
    336     // due to limitations in KURL
    337     response.setTextEncodingName(isBase64 ? charset : "UTF-16");
    338     client->didReceiveResponse(handle, response);
    339 
    340     // The load may be cancelled, and the client may be destroyed
    341     // by any of the client reporting calls, so we check, and bail
    342     // out in either of those cases.
     383    if (isBase64) {
     384        data = decodeURLEscapeSequences(data);
     385        response.setTextEncodingName(charset);
     386        client->didReceiveResponse(handle, response);
     387
     388        // The load may be cancelled, and the client may be destroyed
     389        // by any of the client reporting calls, so we check, and bail
     390        // out in either of those cases.
     391        if (d->m_cancelled || !handle->client())
     392            return false;
     393
     394        // Use the GLib Base64, since WebCore's decoder isn't
     395        // general-purpose and fails on Acid3 test 97 (whitespace).
     396        size_t outLength = 0;
     397        char* outData = 0;
     398        outData = reinterpret_cast<char*>(g_base64_decode(data.utf8().data(), &outLength));
     399        if (outData && outLength > 0)
     400            client->didReceiveData(handle, outData, outLength, 0);
     401        g_free(outData);
     402    } else {
     403        // We have to convert to UTF-16 early due to limitations in KURL
     404        data = decodeURLEscapeSequences(data, TextEncoding(charset));
     405        response.setTextEncodingName("UTF-16");
     406        client->didReceiveResponse(handle, response);
     407
     408        if (d->m_cancelled || !handle->client())
     409            return false;
     410
     411        if (data.length() > 0)
     412            client->didReceiveData(handle, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
     413    }
     414
    343415    if (d->m_cancelled || !handle->client())
    344416        return false;
    345417
    346     SoupSession* session = handle->defaultSession();
    347     GOwnPtr<GError> error;
    348     d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), handle->firstRequest().url().string().utf8().data(), session, &error.outPtr()));
    349     if (error) {
    350         d->m_soupRequest = 0;
    351         return false;
    352     }
    353 
    354     d->m_inputStream = adoptPlatformRef(webkit_soup_request_send(d->m_soupRequest.get(), 0, &error.outPtr()));
    355     if (error) {
    356         d->m_inputStream = 0;
    357         return false;
    358     }
    359 
    360     d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE));
    361     d->m_total = 0;
    362 
    363     g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle);
    364     // balanced by a deref() in cleanupSoupRequestOperation, which should always run
    365     handle->ref();
    366 
    367     d->m_cancellable = adoptPlatformRef(g_cancellable_new());
    368     g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT,
    369                               d->m_cancellable.get(), readCallback, GINT_TO_POINTER(!isBase64));
     418    client->didFinishLoading(handle, 0);
    370419
    371420    return false;
     
    421470}
    422471
    423 static void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroying = false)
    424 {
    425     ResourceHandleInternal* d = handle->getInternal();
    426 
    427     if (d->m_soupRequest) {
    428         g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", 0);
    429         d->m_soupRequest.clear();
    430     }
    431 
    432     if (d->m_inputStream) {
    433         g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", 0);
    434         d->m_inputStream.clear();
    435     }
    436 
    437     d->m_cancellable.clear();
    438 
    439     if (d->m_soupMessage) {
    440         g_signal_handlers_disconnect_matched(d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA,
    441                                              0, 0, 0, 0, handle);
    442         d->m_soupMessage.clear();
    443     }
    444 
    445     if (d->m_buffer) {
    446         g_slice_free1(READ_BUFFER_SIZE, d->m_buffer);
    447         d->m_buffer = 0;
    448     }
    449 
    450     if (!isDestroying)
    451         handle->deref();
    452 }
    453 
    454 static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer userData)
    455 {
    456     RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
    457     if (!handle)
    458         return;
    459 
    460     ResourceHandleInternal* d = handle->getInternal();
    461     ResourceHandleClient* client = handle->client();
    462 
    463     if (d->m_gotChunkHandler) {
    464         // No need to call gotChunkHandler anymore. Received data will
    465         // be reported by readCallback
    466         if (g_signal_handler_is_connected(d->m_soupMessage.get(), d->m_gotChunkHandler))
    467             g_signal_handler_disconnect(d->m_soupMessage.get(), d->m_gotChunkHandler);
    468     }
    469 
    470     if (d->m_cancelled || !client) {
    471         cleanupSoupRequestOperation(handle.get());
    472         return;
    473     }
    474 
    475     GOwnPtr<GError> error;
    476     GInputStream* in = webkit_soup_request_send_finish(d->m_soupRequest.get(), res, &error.outPtr());
    477 
    478     if (error) {
    479         SoupMessage* soupMsg = d->m_soupMessage.get();
    480         gboolean isTransportError = d->m_soupMessage && SOUP_STATUS_IS_TRANSPORT_ERROR(soupMsg->status_code);
    481 
    482         if (isTransportError || (error->domain == G_IO_ERROR)) {
    483             SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get());
    484             GOwnPtr<char> uriStr(soup_uri_to_string(uri, false));
    485             gint errorCode = isTransportError ? soupMsg->status_code : error->code;
    486             const gchar* errorMsg = isTransportError ? soupMsg->reason_phrase : error->message;
    487             const gchar* quarkStr = isTransportError ? g_quark_to_string(SOUP_HTTP_ERROR) : g_quark_to_string(G_IO_ERROR);
    488             ResourceError resourceError(quarkStr, errorCode, uriStr.get(), String::fromUTF8(errorMsg));
    489 
    490             cleanupSoupRequestOperation(handle.get());
    491             client->didFail(handle.get(), resourceError);
    492             return;
    493         }
    494 
    495         if (d->m_soupMessage && soupMessage->status_code == SOUP_STATUS_UNAUTHORIZED) {
    496             fillResponseFromMessage(soupMsg, &d->m_response);
    497             client->didReceiveResponse(handle.get(), d->m_response);
    498 
    499             // WebCore might have cancelled the job in the while
    500             if (!d->m_cancelled && soupMsg->response_body->data)
    501                 client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, true);
    502         }
    503 
    504         // didReceiveData above might have cancelled it
    505         if (d->m_cancelled || !client) {
    506             cleanupSoupRequestOperation(handle.get());
    507             return;
    508         }
    509 
    510         client->didFinishLoading(handle.get(), 0);
    511         return;
    512     }
    513 
    514     if (d->m_cancelled) {
    515         cleanupSoupRequestOperation(handle.get());
    516         return;
    517     }
    518 
    519     d->m_inputStream = adoptPlatformRef(in);
    520     d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE));
    521     d->m_total = 0;
    522 
    523     // readCallback needs it
    524     g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle.get());
    525 
    526     // We need to check if it's a file: URL and if it is a regular
    527     // file as it could be a directory. In that case Soup properly
    528     // returns a stream whose content is a HTML with a list of files
    529     // in the directory
    530     if (equalIgnoringCase(handle->firstRequest().url().protocol(), "file")
    531         && G_IS_FILE_INPUT_STREAM(in)) {
    532         ResourceResponse response;
    533 
    534         response.setURL(handle->firstRequest().url());
    535         response.setMimeType(webkit_soup_request_get_content_type(d->m_soupRequest.get()));
    536         response.setExpectedContentLength(webkit_soup_request_get_content_length(d->m_soupRequest.get()));
    537         client->didReceiveResponse(handle.get(), response);
    538 
    539         if (d->m_cancelled) {
    540             cleanupSoupRequestOperation(handle.get());
    541             return;
    542         }
    543     }
    544 
    545     g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE,
    546                               G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, 0);
    547 }
    548 
    549472static bool startHttp(ResourceHandle* handle)
    550473{
     
    561484    request.setURL(url);
    562485
    563     GOwnPtr<GError> error;
    564     d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), url.string().utf8().data(), session, &error.outPtr()));
    565     if (error) {
    566         d->m_soupRequest = 0;
     486    d->m_msg = request.toSoupMessage();
     487    if (!d->m_msg)
    567488        return false;
    568     }
    569 
    570     g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle);
    571 
    572     d->m_soupMessage = adoptPlatformRef(webkit_soup_request_http_get_message(WEBKIT_SOUP_REQUEST_HTTP(d->m_soupRequest.get())));
    573     if (!d->m_soupMessage)
    574         return false;
    575 
    576     SoupMessage* soupMessage = d->m_soupMessage.get();
    577     request.updateSoupMessage(soupMessage);
    578489
    579490    if (!handle->shouldContentSniff())
    580         soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER);
    581 
    582     g_signal_connect(soupMessage, "restarted", G_CALLBACK(restartedCallback), handle);
    583     g_signal_connect(soupMessage, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
    584     g_signal_connect(soupMessage, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle);
    585     d->m_gotChunkHandler = g_signal_connect(soupMessage, "got-chunk", G_CALLBACK(gotChunkCallback), handle);
     491        soup_message_disable_feature(d->m_msg, SOUP_TYPE_CONTENT_SNIFFER);
     492
     493    g_signal_connect(d->m_msg, "restarted", G_CALLBACK(restartedCallback), handle);
     494    g_signal_connect(d->m_msg, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
     495    g_signal_connect(d->m_msg, "content-sniffed", G_CALLBACK(contentSniffedCallback), handle);
     496    g_signal_connect(d->m_msg, "got-chunk", G_CALLBACK(gotChunkCallback), handle);
    586497
    587498#ifdef HAVE_LIBSOUP_2_29_90
     
    589500    if (!firstPartyString.isEmpty()) {
    590501        GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
    591         soup_message_set_first_party(soupMessage, firstParty.get());
     502        soup_message_set_first_party(d->m_msg, firstParty.get());
    592503    }
    593504#endif
     505    g_object_set_data(G_OBJECT(d->m_msg), "resourceHandle", reinterpret_cast<void*>(handle));
    594506
    595507    FormData* httpBody = d->m_firstRequest.httpBody();
     
    601513            Vector<char> body;
    602514            httpBody->flatten(body);
    603             soup_message_set_request(soupMessage, d->m_firstRequest.httpContentType().utf8().data(),
     515            soup_message_set_request(d->m_msg, d->m_firstRequest.httpContentType().utf8().data(),
    604516                                     SOUP_MEMORY_COPY, body.data(), body.size());
    605517        } else {
     
    610522             * (think sftp://) files by using GIO?
    611523             */
    612             soup_message_body_set_accumulate(soupMessage->request_body, FALSE);
     524            soup_message_body_set_accumulate(d->m_msg->request_body, FALSE);
    613525            for (size_t i = 0; i < numElements; i++) {
    614526                const FormDataElement& element = httpBody->elements()[i];
    615527
    616528                if (element.m_type == FormDataElement::data)
    617                     soup_message_body_append(soupMessage->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size());
     529                    soup_message_body_append(d->m_msg->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size());
    618530                else {
    619531                    /*
     
    621533                     * libsoup's simple-httpd test
    622534                     */
    623                     GOwnPtr<GError> error;
     535                    GError* error = 0;
    624536                    CString fileName = fileSystemRepresentation(element.m_filename);
    625                     GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error.outPtr());
     537                    GMappedFile* fileMapping = g_mapped_file_new(fileName.data(), false, &error);
    626538
    627539                    if (error) {
    628                         g_signal_handlers_disconnect_matched(soupMessage, G_SIGNAL_MATCH_DATA,
     540                        g_error_free(error);
     541                        g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA,
    629542                                                             0, 0, 0, 0, handle);
    630                         d->m_soupMessage.clear();
     543                        g_object_unref(d->m_msg);
     544                        d->m_msg = 0;
    631545
    632546                        return false;
     
    636550                                                                        g_mapped_file_get_length(fileMapping),
    637551                                                                        fileMapping,
     552#if GLIB_CHECK_VERSION(2, 21, 3)
    638553                                                                        reinterpret_cast<GDestroyNotify>(g_mapped_file_unref));
    639                     soup_message_body_append_buffer(soupMessage->request_body, soupBuffer);
     554#else
     555                                                                        reinterpret_cast<GDestroyNotify>(g_mapped_file_free));
     556#endif
     557                    soup_message_body_append_buffer(d->m_msg->request_body, soupBuffer);
    640558                    soup_buffer_free(soupBuffer);
    641559                }
     
    644562    }
    645563
    646     // balanced by a deref() in cleanupSoupRequestOperation, which should always run
     564    // balanced by a deref() in finishedCallback, which should always run
    647565    handle->ref();
    648566
    649567    // Make sure we have an Accept header for subresources; some sites
    650568    // want this to serve some of their subresources
    651     if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept"))
    652         soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
    653 
    654     d->m_cancellable = adoptPlatformRef(g_cancellable_new());
    655     webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0);
     569    if (!soup_message_headers_get_one(d->m_msg->request_headers, "Accept"))
     570        soup_message_headers_append(d->m_msg->request_headers, "Accept", "*/*");
     571
     572    // Balanced in ResourceHandleInternal's destructor; we need to
     573    // keep our own ref, because after queueing the message, the
     574    // session owns the initial reference.
     575    g_object_ref(d->m_msg);
     576    soup_session_queue_message(session, d->m_msg, finishedCallback, handle);
    656577
    657578    return true;
     
    660581bool ResourceHandle::start(NetworkingContext* context)
    661582{
    662     ASSERT(!d->m_soupMessage);
     583    ASSERT(!d->m_msg);
    663584
    664585    // The frame could be null if the ResourceHandle is not associated to any
     
    700621{
    701622    d->m_cancelled = true;
    702     if (d->m_soupMessage)
    703         soup_session_cancel_message(defaultSession(), d->m_soupMessage.get(), SOUP_STATUS_CANCELLED);
     623    if (d->m_msg)
     624        soup_session_cancel_message(defaultSession(), d->m_msg, SOUP_STATUS_CANCELLED);
    704625    else if (d->m_cancellable)
    705         g_cancellable_cancel(d->m_cancellable.get());
     626        g_cancellable_cancel(d->m_cancellable);
    706627}
    707628
     
    747668}
    748669
     670// GIO-based loader
     671
     672static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying = false)
     673{
     674    ResourceHandleInternal* d = handle->getInternal();
     675
     676    if (d->m_gfile) {
     677        g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", 0);
     678        g_object_unref(d->m_gfile);
     679        d->m_gfile = 0;
     680    }
     681
     682    if (d->m_cancellable) {
     683        g_object_unref(d->m_cancellable);
     684        d->m_cancellable = 0;
     685    }
     686
     687    if (d->m_inputStream) {
     688        g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", 0);
     689        g_object_unref(d->m_inputStream);
     690        d->m_inputStream = 0;
     691    }
     692
     693    if (d->m_buffer) {
     694        g_free(d->m_buffer);
     695        d->m_buffer = 0;
     696    }
     697
     698    if (!isDestroying)
     699        handle->deref();
     700}
     701
    749702static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
    750703{
     
    756709    ResourceHandleClient* client = handle->client();
    757710
    758     g_input_stream_close_finish(d->m_inputStream.get(), res, 0);
    759     cleanupSoupRequestOperation(handle.get());
     711    g_input_stream_close_finish(d->m_inputStream, res, 0);
     712    cleanupGioOperation(handle.get());
    760713
    761714    // The load may have been cancelled, the client may have been
     
    768721}
    769722
    770 static void readCallback(GObject* source, GAsyncResult* asyncResult, gpointer data)
     723static void readCallback(GObject* source, GAsyncResult* res, gpointer)
    771724{
    772725    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
     
    774727        return;
    775728
    776     bool convertToUTF16 = static_cast<bool>(data);
    777729    ResourceHandleInternal* d = handle->getInternal();
    778730    ResourceHandleClient* client = handle->client();
    779731
    780732    if (d->m_cancelled || !client) {
    781         cleanupSoupRequestOperation(handle.get());
    782         return;
    783     }
    784 
    785     GOwnPtr<GError> error;
    786 
    787     gssize bytesRead = g_input_stream_read_finish(d->m_inputStream.get(), asyncResult, &error.outPtr());
     733        cleanupGioOperation(handle.get());
     734        return;
     735    }
     736
     737    GError* error = 0;
     738
     739    gssize bytesRead = g_input_stream_read_finish(d->m_inputStream, res, &error);
    788740    if (error) {
    789         SoupURI* uri = webkit_soup_request_get_uri(d->m_soupRequest.get());
    790         GOwnPtr<char> uriStr(soup_uri_to_string(uri, false));
    791         ResourceError resourceError(g_quark_to_string(G_IO_ERROR), error->code, uriStr.get(),
     741        char* uri = g_file_get_uri(d->m_gfile);
     742        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
     743                                    error->code,
     744                                    uri,
    792745                                    error ? String::fromUTF8(error->message) : String());
    793         cleanupSoupRequestOperation(handle.get());
     746        g_free(uri);
     747        g_error_free(error);
     748        cleanupGioOperation(handle.get());
    794749        client->didFail(handle.get(), resourceError);
    795750        return;
     
    797752
    798753    if (!bytesRead) {
    799         g_input_stream_close_async(d->m_inputStream.get(), G_PRIORITY_DEFAULT,
     754        g_input_stream_close_async(d->m_inputStream, G_PRIORITY_DEFAULT,
    800755                                   0, closeCallback, 0);
    801756        return;
     
    803758
    804759    d->m_total += bytesRead;
    805     if (G_LIKELY(!convertToUTF16))
    806         client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total);
    807     else {
    808         // We have to convert it to UTF-16 due to limitations in KURL
    809         String data = String::fromUTF8(d->m_buffer, bytesRead);
    810         client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
    811     }
     760    client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total);
    812761
    813762    // didReceiveData may cancel the load, which may release the last reference.
     763    if (d->m_cancelled) {
     764        cleanupGioOperation(handle.get());
     765        return;
     766    }
     767
     768    g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
     769                              G_PRIORITY_DEFAULT, d->m_cancellable,
     770                              readCallback, 0);
     771}
     772
     773static void openCallback(GObject* source, GAsyncResult* res, gpointer)
     774{
     775    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
     776    if (!handle)
     777        return;
     778
     779    ResourceHandleInternal* d = handle->getInternal();
     780    ResourceHandleClient* client = handle->client();
     781
    814782    if (d->m_cancelled || !client) {
    815         cleanupSoupRequestOperation(handle.get());
    816         return;
    817     }
    818 
    819     g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT,
    820                               d->m_cancellable.get(), readCallback, data);
    821 }
    822 
     783        cleanupGioOperation(handle.get());
     784        return;
     785    }
     786
     787    GError* error = 0;
     788    GFileInputStream* in = g_file_read_finish(G_FILE(source), res, &error);
     789    if (error) {
     790        char* uri = g_file_get_uri(d->m_gfile);
     791        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
     792                                    error->code,
     793                                    uri,
     794                                    error ? String::fromUTF8(error->message) : String());
     795        g_free(uri);
     796        g_error_free(error);
     797        cleanupGioOperation(handle.get());
     798        client->didFail(handle.get(), resourceError);
     799        return;
     800    }
     801
     802    d->m_inputStream = G_INPUT_STREAM(in);
     803    d->m_bufferSize = 8192;
     804    d->m_buffer = static_cast<char*>(g_malloc(d->m_bufferSize));
     805    d->m_total = 0;
     806
     807    g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle.get());
     808    g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
     809                              G_PRIORITY_DEFAULT, d->m_cancellable,
     810                              readCallback, 0);
     811}
     812
     813static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
     814{
     815    RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
     816    if (!handle)
     817        return;
     818
     819    ResourceHandleInternal* d = handle->getInternal();
     820    ResourceHandleClient* client = handle->client();
     821
     822    if (d->m_cancelled) {
     823        cleanupGioOperation(handle.get());
     824        return;
     825    }
     826
     827    ResourceResponse response;
     828
     829    char* uri = g_file_get_uri(d->m_gfile);
     830    response.setURL(KURL(KURL(), uri));
     831    g_free(uri);
     832
     833    GError* error = 0;
     834    GFileInfo* info = g_file_query_info_finish(d->m_gfile, res, &error);
     835
     836    if (error) {
     837        // FIXME: to be able to handle ftp URIs properly, we must
     838        // check if the error is G_IO_ERROR_NOT_MOUNTED, and if so,
     839        // call g_file_mount_enclosing_volume() to mount the ftp
     840        // server (and then keep track of the fact that we mounted it,
     841        // and set a timeout to unmount it later after it's been idle
     842        // for a while).
     843        char* uri = g_file_get_uri(d->m_gfile);
     844        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
     845                                    error->code,
     846                                    uri,
     847                                    error ? String::fromUTF8(error->message) : String());
     848        g_free(uri);
     849        g_error_free(error);
     850        cleanupGioOperation(handle.get());
     851        client->didFail(handle.get(), resourceError);
     852        return;
     853    }
     854
     855    if (g_file_info_get_file_type(info) != G_FILE_TYPE_REGULAR) {
     856        // FIXME: what if the URI points to a directory? Should we
     857        // generate a listing? How? What do other backends do here?
     858        char* uri = g_file_get_uri(d->m_gfile);
     859        ResourceError resourceError(g_quark_to_string(G_IO_ERROR),
     860                                    G_IO_ERROR_FAILED,
     861                                    uri,
     862                                    String());
     863        g_free(uri);
     864        cleanupGioOperation(handle.get());
     865        client->didFail(handle.get(), resourceError);
     866        return;
     867    }
     868
     869    // According to http://library.gnome.org/devel/gio/stable/gio-GContentType.html
     870    // GContentType on Unix is the mime type, but not on Win32.
     871    GOwnPtr<gchar> mimeType(g_content_type_get_mime_type(g_file_info_get_content_type(info)));
     872    response.setMimeType(mimeType.get());
     873    response.setExpectedContentLength(g_file_info_get_size(info));
     874
     875    GTimeVal tv;
     876    g_file_info_get_modification_time(info, &tv);
     877    response.setLastModifiedDate(tv.tv_sec);
     878
     879    client->didReceiveResponse(handle.get(), response);
     880
     881    if (d->m_cancelled) {
     882        cleanupGioOperation(handle.get());
     883        return;
     884    }
     885
     886    g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable,
     887                      openCallback, 0);
     888}
    823889static bool startGio(ResourceHandle* handle, KURL url)
    824890{
    825891    ASSERT(handle);
     892
     893    ResourceHandleInternal* d = handle->getInternal();
    826894
    827895    if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST")
    828896        return false;
    829 
    830     SoupSession* session = handle->defaultSession();
    831     ResourceHandleInternal* d = handle->getInternal();
    832897
    833898    // GIO doesn't know how to handle refs and queries, so remove them
     
    837902    url.setQuery(String());
    838903    url.removePort();
    839     CString urlStr = url.string().utf8();
    840 
    841     GOwnPtr<GError> error;
    842     d->m_soupRequest = adoptPlatformRef(webkit_soup_requester_request(d->m_requester.get(), urlStr.data(), session, &error.outPtr()));
    843     if (error) {
    844         d->m_soupRequest = 0;
    845         return false;
    846     }
    847 
    848     g_object_set_data(G_OBJECT(d->m_soupRequest.get()), "webkit-resource", handle);
    849 
    850     // balanced by a deref() in cleanupSoupRequestOperation, which should always run
     904
     905#if !OS(WINDOWS)
     906    // we avoid the escaping for local files, because
     907    // g_filename_from_uri (used internally by GFile) has problems
     908    // decoding strings with arbitrary percent signs
     909    if (url.isLocalFile())
     910        d->m_gfile = g_file_new_for_path(url.prettyURL().utf8().data() + sizeof("file://") - 1);
     911    else
     912#endif
     913        d->m_gfile = g_file_new_for_uri(url.string().utf8().data());
     914    g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", handle);
     915
     916    // balanced by a deref() in cleanupGioOperation, which should always run
    851917    handle->ref();
    852918
    853     d->m_cancellable = adoptPlatformRef(g_cancellable_new());
    854     webkit_soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, 0);
    855 
     919    d->m_cancellable = g_cancellable_new();
     920    g_file_query_info_async(d->m_gfile,
     921                            G_FILE_ATTRIBUTE_STANDARD_TYPE ","
     922                            G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
     923                            G_FILE_ATTRIBUTE_STANDARD_SIZE,
     924                            G_FILE_QUERY_INFO_NONE,
     925                            G_PRIORITY_DEFAULT, d->m_cancellable,
     926                            queryInfoCallback, 0);
    856927    return true;
    857928}
  • trunk/WebCore/platform/network/soup/ResourceRequest.h

    r69589 r69606  
    6868        }
    6969
    70         void updateSoupMessage(SoupMessage*) const;
    7170        SoupMessage* toSoupMessage() const;
    72         void updateFromSoupMessage(SoupMessage*);
     71        void updateFromSoupMessage(SoupMessage* soupMessage);
    7372
    7473        SoupMessageFlags soupMessageFlags() const { return m_soupFlags; }
  • trunk/WebCore/platform/network/soup/ResourceRequestSoup.cpp

    r69589 r69606  
    3333
    3434namespace WebCore {
    35 
    36 void ResourceRequest::updateSoupMessage(SoupMessage* soupMessage) const
    37 {
    38     g_object_set(soupMessage, SOUP_MESSAGE_METHOD, httpMethod().utf8().data(), NULL);
    39 
    40     const HTTPHeaderMap& headers = httpHeaderFields();
    41     SoupMessageHeaders* soupHeaders = soupMessage->request_headers;
    42     if (!headers.isEmpty()) {
    43         HTTPHeaderMap::const_iterator end = headers.end();
    44         for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
    45             soup_message_headers_append(soupHeaders, it->first.string().utf8().data(), it->second.utf8().data());
    46     }
    47 
    48 #ifdef HAVE_LIBSOUP_2_29_90
    49     String firstPartyString = firstPartyForCookies().string();
    50     if (!firstPartyString.isEmpty()) {
    51         GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
    52         soup_message_set_first_party(soupMessage, firstParty.get());
    53     }
    54 #endif
    55 
    56     soup_message_set_flags(soupMessage, m_soupFlags);
    57 }
    5835
    5936SoupMessage* ResourceRequest::toSoupMessage() const
  • trunk/WebKit/gtk/ChangeLog

    r69589 r69606  
     12010-10-12  Sheriff Bot  <webkit.review.bot@gmail.com>
     2
     3        Unreviewed, rolling out r69589.
     4        http://trac.webkit.org/changeset/69589
     5        https://bugs.webkit.org/show_bug.cgi?id=47547
     6
     7        Wrong patch landed from a bug with two patches (Requested by
     8        mrobinson on #webkit).
     9
     10        * webkit/webkitdownload.cpp:
     11        (webkit_download_new_with_handle):
     12        (webkit_download_start):
     13
    1142010-10-12  Sergio Villar Senin  <svillar@igalia.com>
    215
  • trunk/WebKit/gtk/webkit/webkitdownload.cpp

    r69589 r69606  
    420420
    421421    ResourceHandleInternal* d = handle->getInternal();
    422     if (d->m_soupMessage)
    423         soup_session_pause_message(webkit_get_default_session(), d->m_soupMessage.get());
     422    if (d->m_msg)
     423        soup_session_pause_message(webkit_get_default_session(), d->m_msg);
    424424
    425425    WebKitDownload* download = WEBKIT_DOWNLOAD(g_object_new(WEBKIT_TYPE_DOWNLOAD, "network-request", request, NULL));
     
    493493
    494494        ResourceHandleInternal* d = priv->resourceHandle->getInternal();
    495         if (d->m_soupMessage)
    496             soup_session_unpause_message(webkit_get_default_session(), d->m_soupMessage.get());
     495        if (d->m_msg)
     496            soup_session_unpause_message(webkit_get_default_session(), d->m_msg);
    497497    }
    498498
Note: See TracChangeset for help on using the changeset viewer.