⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resourcehandlemanager.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}void ResourceHandleManager::setupPUT(ResourceHandle*, struct curl_slist**){    notImplemented();}/* Calculate the length of the POST.   Force chunked data transfer if size of files can't be obtained. */void ResourceHandleManager::setupPOST(ResourceHandle* job, struct curl_slist** headers){    ResourceHandleInternal* d = job->getInternal();    curl_easy_setopt(d->m_handle, CURLOPT_POST, TRUE);    curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE, 0);    if (!job->request().httpBody())        return;    Vector<FormDataElement> elements = job->request().httpBody()->elements();    size_t numElements = elements.size();    if (!numElements)        return;    // Do not stream for simple POST data    if (numElements == 1) {        job->request().httpBody()->flatten(d->m_postBytes);        if (d->m_postBytes.size() != 0) {            curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE, d->m_postBytes.size());            curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDS, d->m_postBytes.data());        }        return;    }    // Obtain the total size of the POST    // The size of a curl_off_t could be different in WebKit and in cURL depending on    // compilation flags of both. For CURLOPT_POSTFIELDSIZE_LARGE we have to pass the    // right size or random data will be used as the size.    static int expectedSizeOfCurlOffT = 0;    if (!expectedSizeOfCurlOffT) {        curl_version_info_data *infoData = curl_version_info(CURLVERSION_NOW);        if (infoData->features & CURL_VERSION_LARGEFILE)            expectedSizeOfCurlOffT = sizeof(long long);        else            expectedSizeOfCurlOffT = sizeof(int);    }#if COMPILER(MSVC)    // work around compiler error in Visual Studio 2005.  It can't properly    // handle math with 64-bit constant declarations.#pragma warning(disable: 4307)#endif    static const long long maxCurlOffT = (1LL << (expectedSizeOfCurlOffT * 8 - 1)) - 1;    curl_off_t size = 0;    bool chunkedTransfer = false;    for (size_t i = 0; i < numElements; i++) {        FormDataElement element = elements[i];        if (element.m_type == FormDataElement::encodedFile) {            long long fileSizeResult;            if (getFileSize(element.m_filename, fileSizeResult)) {                if (fileSizeResult > maxCurlOffT) {                    // File size is too big for specifying it to cURL                    chunkedTransfer = true;                    break;                }                size += fileSizeResult;            } else {                chunkedTransfer = true;                break;            }        } else            size += elements[i].m_data.size();    }    // cURL guesses that we want chunked encoding as long as we specify the header    if (chunkedTransfer)        *headers = curl_slist_append(*headers, "Transfer-Encoding: chunked");    else {        if (sizeof(long long) == expectedSizeOfCurlOffT)          curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE_LARGE, (long long)size);        else          curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE_LARGE, (int)size);    }    curl_easy_setopt(d->m_handle, CURLOPT_READFUNCTION, readCallback);    curl_easy_setopt(d->m_handle, CURLOPT_READDATA, job);}void ResourceHandleManager::add(ResourceHandle* job){    // we can be called from within curl, so to avoid re-entrancy issues    // schedule this job to be added the next time we enter curl download loop    job->ref();    m_resourceHandleList.append(job);    if (!m_downloadTimer.isActive())        m_downloadTimer.startOneShot(pollTimeSeconds);}bool ResourceHandleManager::removeScheduledJob(ResourceHandle* job){    int size = m_resourceHandleList.size();    for (int i = 0; i < size; i++) {        if (job == m_resourceHandleList[i]) {            m_resourceHandleList.remove(i);            job->deref();            return true;        }    }    return false;}bool ResourceHandleManager::startScheduledJobs(){    // TODO: Create a separate stack of jobs for each domain.    bool started = false;    while (!m_resourceHandleList.isEmpty() && m_runningJobs < maxRunningJobs) {        ResourceHandle* job = m_resourceHandleList[0];        m_resourceHandleList.remove(0);        startJob(job);        started = true;    }    return started;}static void parseDataUrl(ResourceHandle* handle){    ResourceHandleClient* client = handle->client();    ASSERT(client);    if (!client)        return;    String url = handle->request().url().string();    ASSERT(url.startsWith("data:", false));    int index = url.find(',');    if (index == -1) {        client->cannotShowURL(handle);        return;    }    String mediaType = url.substring(5, index - 5);    String data = url.substring(index + 1);    bool base64 = mediaType.endsWith(";base64", false);    if (base64)        mediaType = mediaType.left(mediaType.length() - 7);    if (mediaType.isEmpty())        mediaType = "text/plain;charset=US-ASCII";    String mimeType = extractMIMETypeFromMediaType(mediaType);    String charset = extractCharsetFromMediaType(mediaType);    ResourceResponse response;    response.setMimeType(mimeType);    if (base64) {        data = decodeURLEscapeSequences(data);        response.setTextEncodingName(charset);        client->didReceiveResponse(handle, response);        // Use the GLib Base64 if available, since WebCore's decoder isn't        // general-purpose and fails on Acid3 test 97 (whitespace).#ifdef USE_GLIB_BASE64        size_t outLength = 0;        char* outData = 0;        outData = reinterpret_cast<char*>(g_base64_decode(data.utf8().data(), &outLength));        if (outData && outLength > 0)            client->didReceiveData(handle, outData, outLength, 0);        g_free(outData);#else        Vector<char> out;        if (base64Decode(data.latin1().data(), data.latin1().length(), out) && out.size() > 0)            client->didReceiveData(handle, out.data(), out.size(), 0);#endif    } else {        // We have to convert to UTF-16 early due to limitations in KURL        data = decodeURLEscapeSequences(data, TextEncoding(charset));        response.setTextEncodingName("UTF-16");        client->didReceiveResponse(handle, response);        if (data.length() > 0)            client->didReceiveData(handle, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);    }    client->didFinishLoading(handle);}void ResourceHandleManager::dispatchSynchronousJob(ResourceHandle* job){    KURL kurl = job->request().url();    if (kurl.protocolIs("data")) {        parseDataUrl(job);        return;    }    ResourceHandleInternal* handle = job->getInternal();#if LIBCURL_VERSION_NUM > 0x071200    // If defersLoading is true and we call curl_easy_perform    // on a paused handle, libcURL would do the transfert anyway    // and we would assert so force defersLoading to be false.    handle->m_defersLoading = false;#endif    initializeHandle(job);    // curl_easy_perform blocks until the transfert is finished.    CURLcode ret =  curl_easy_perform(handle->m_handle);    if (ret != 0) {        ResourceError error(String(handle->m_url), ret, String(handle->m_url), String(curl_easy_strerror(ret)));        handle->client()->didFail(job, error);    }    curl_easy_cleanup(handle->m_handle);}void ResourceHandleManager::startJob(ResourceHandle* job){    KURL kurl = job->request().url();    if (kurl.protocolIs("data")) {        parseDataUrl(job);        return;    }    initializeHandle(job);    m_runningJobs++;    CURLMcode ret = curl_multi_add_handle(m_curlMultiHandle, job->getInternal()->m_handle);    // don't call perform, because events must be async    // timeout will occur and do curl_multi_perform    if (ret && ret != CURLM_CALL_MULTI_PERFORM) {#ifndef NDEBUG        fprintf(stderr, "Error %d starting job %s\n", ret, encodeWithURLEscapeSequences(job->request().url().string()).latin1().data());#endif        job->cancel();        return;    }}void ResourceHandleManager::initializeHandle(ResourceHandle* job){    KURL kurl = job->request().url();    // Remove any fragment part, otherwise curl will send it as part of the request.    kurl.removeRef();    ResourceHandleInternal* d = job->getInternal();    String url = kurl.string();    if (kurl.isLocalFile()) {        String query = kurl.query();        // Remove any query part sent to a local file.        if (!query.isEmpty())            url = url.left(url.find(query));        // Determine the MIME type based on the path.        d->m_response.setMimeType(MIMETypeRegistry::getMIMETypeForPath(url));    }    d->m_handle = curl_easy_init();#if LIBCURL_VERSION_NUM > 0x071200    if (d->m_defersLoading) {        CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_ALL);        // If we did not pause the handle, we would ASSERT in the        // header callback. So just assert here.        ASSERT(error == CURLE_OK);    }#endif#ifndef NDEBUG    if (getenv("DEBUG_CURL"))        curl_easy_setopt(d->m_handle, CURLOPT_VERBOSE, 1);#endif    curl_easy_setopt(d->m_handle, CURLOPT_PRIVATE, job);    curl_easy_setopt(d->m_handle, CURLOPT_ERRORBUFFER, m_curlErrorBuffer);    curl_easy_setopt(d->m_handle, CURLOPT_WRITEFUNCTION, writeCallback);    curl_easy_setopt(d->m_handle, CURLOPT_WRITEDATA, job);    curl_easy_setopt(d->m_handle, CURLOPT_HEADERFUNCTION, headerCallback);    curl_easy_setopt(d->m_handle, CURLOPT_WRITEHEADER, job);    curl_easy_setopt(d->m_handle, CURLOPT_AUTOREFERER, 1);    curl_easy_setopt(d->m_handle, CURLOPT_FOLLOWLOCATION, 1);    curl_easy_setopt(d->m_handle, CURLOPT_MAXREDIRS, 10);    curl_easy_setopt(d->m_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);    curl_easy_setopt(d->m_handle, CURLOPT_SHARE, m_curlShareHandle);    curl_easy_setopt(d->m_handle, CURLOPT_DNS_CACHE_TIMEOUT, 60 * 5); // 5 minutes    // FIXME: Enable SSL verification when we have a way of shipping certs    // and/or reporting SSL errors to the user.    if (ignoreSSLErrors)        curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, false);    // enable gzip and deflate through Accept-Encoding:    curl_easy_setopt(d->m_handle, CURLOPT_ENCODING, "");    // url must remain valid through the request    ASSERT(!d->m_url);    // url is in ASCII so latin1() will only convert it to char* without character translation.    d->m_url = strdup(url.latin1().data());    curl_easy_setopt(d->m_handle, CURLOPT_URL, d->m_url);    if (m_cookieJarFileName) {        curl_easy_setopt(d->m_handle, CURLOPT_COOKIEFILE, m_cookieJarFileName);        curl_easy_setopt(d->m_handle, CURLOPT_COOKIEJAR, m_cookieJarFileName);    }    struct curl_slist* headers = 0;    if (job->request().httpHeaderFields().size() > 0) {        HTTPHeaderMap customHeaders = job->request().httpHeaderFields();        HTTPHeaderMap::const_iterator end = customHeaders.end();        for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it) {            String key = it->first;            String value = it->second;            String headerString(key);            headerString.append(": ");            headerString.append(value);            CString headerLatin1 = headerString.latin1();            headers = curl_slist_append(headers, headerLatin1.data());        }    }    if ("GET" == job->request().httpMethod())        curl_easy_setopt(d->m_handle, CURLOPT_HTTPGET, TRUE);    else if ("POST" == job->request().httpMethod())        setupPOST(job, &headers);    else if ("PUT" == job->request().httpMethod())        setupPUT(job, &headers);    else if ("HEAD" == job->request().httpMethod())        curl_easy_setopt(d->m_handle, CURLOPT_NOBODY, TRUE);    if (headers) {        curl_easy_setopt(d->m_handle, CURLOPT_HTTPHEADER, headers);        d->m_customHeaders = headers;    }}void ResourceHandleManager::cancel(ResourceHandle* job){    if (removeScheduledJob(job))        return;    ResourceHandleInternal* d = job->getInternal();    d->m_cancelled = true;    if (!m_downloadTimer.isActive())        m_downloadTimer.startOneShot(pollTimeSeconds);}} // namespace WebCore

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -