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

📄 qwebnetworkinterface.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
*/QWebNetworkManager::QWebNetworkManager()    : QObject(0)    , m_scheduledWork(false){    connect(this, SIGNAL(scheduleWork()), SLOT(doWork()), Qt::QueuedConnection);}QWebNetworkManager *QWebNetworkManager::self(){    // ensure everything's constructed and connected    QWebNetworkInterface::defaultInterface();    return s_manager;}bool QWebNetworkManager::add(ResourceHandle *handle, QWebNetworkInterface *interface, JobMode jobMode){    if (!interface)        interface = s_default_interface;    ASSERT(interface);    QWebNetworkJob *job = new QWebNetworkJob();    handle->getInternal()->m_job = job;    job->d->resourceHandle = handle;    job->d->interface = interface;    job->d->request.init(handle->request());    const QString method = handle->getInternal()->m_request.httpMethod();    if (method != "POST" && method != "GET" && method != "HEAD") {        qWarning("REQUEST: [%s]\n", qPrintable(job->d->request.httpHeader.toString()));        return false;    }    DEBUG() << "QWebNetworkManager::add:" <<  job->d->request.httpHeader.toString();    if (jobMode == SynchronousJob) {        Q_ASSERT(!m_synchronousJobs.contains(job));        m_synchronousJobs[job] = 1;    }    interface->addJob(job);    return true;}void QWebNetworkManager::cancel(ResourceHandle *handle){    QWebNetworkJob *job = handle->getInternal()->m_job;    if (!job)        return;    DEBUG() << "QWebNetworkManager::cancel:" <<  job->d->request.httpHeader.toString();    job->d->resourceHandle = 0;    job->d->interface->cancelJob(job);    handle->getInternal()->m_job = 0;}void QWebNetworkManager::started(QWebNetworkJob *job){    Q_ASSERT(job->d);    Q_ASSERT(job->status() == QWebNetworkJob::JobCreated ||             job->status() == QWebNetworkJob::JobRecreated);    job->setStatus(QWebNetworkJob::JobStarted);    ResourceHandleClient* client = 0;    if (job->d->resourceHandle) {        client = job->d->resourceHandle->client();        if (!client)            return;    } else {        return;    }    DEBUG() << "ResourceHandleManager::receivedResponse:";    DEBUG() << job->d->response.toString();    QStringList cookies = job->d->response.allValues("Set-Cookie");    KURL url(job->url());    foreach (QString c, cookies) {        QCookieJar::cookieJar()->setCookies(url, url, c);    }    QString contentType = job->d->response.value("Content-Type");    QString encoding;    int idx = contentType.indexOf(QLatin1Char(';'));    if (idx > 0) {        QString remainder = contentType.mid(idx + 1).toLower();        contentType = contentType.left(idx).trimmed();        idx = remainder.indexOf("charset");        if (idx >= 0) {            idx = remainder.indexOf(QLatin1Char('='), idx);            if (idx >= 0)                encoding = remainder.mid(idx + 1).trimmed();        }    }    if (contentType.isEmpty()) {        // let's try to guess from the extension        QString extension = job->d->request.url.path();        int index = extension.lastIndexOf(QLatin1Char('.'));        if (index > 0) {            extension = extension.mid(index + 1);            contentType = MIMETypeRegistry::getMIMETypeForExtension(extension);        }    }//     qDebug() << "Content-Type=" << contentType;//     qDebug() << "Encoding=" << encoding;    ResourceResponse response(url, contentType,                              0 /* FIXME */,                              encoding,                              String() /* FIXME */);    int statusCode = job->d->response.statusCode();    if (job->url().scheme() != QLatin1String("file"))        response.setHTTPStatusCode(statusCode);    else if (statusCode == 404)        response.setHTTPStatusCode(statusCode);    /* Fill in the other fields */    if (statusCode >= 300 && statusCode < 400) {        // we're on a redirect page! if the 'Location:' field is valid, we redirect        QString location = job->d->response.value("location");        DEBUG() << "Redirection";        if (!location.isEmpty()) {            QUrl newUrl = job->d->request.url.resolved(location);            if (job->d->resourceHandle) {                ResourceRequest newRequest = job->d->resourceHandle->request();                newRequest.setURL(KURL(newUrl));                if (client)                    client->willSendRequest(job->d->resourceHandle, newRequest, response);            }            QString method;            if (statusCode == 302 || statusCode == 303) {                // this is standard-correct for 303 and practically-correct (no standard-correct) for 302                // also, it's required for Yahoo's login process for flickr.com which responds to a POST                // with a 302 which must be GET'ed                method = "GET";                job->d->request.httpHeader.setContentLength(0);            } else {                method = job->d->request.httpHeader.method();            }            job->d->request.httpHeader.setRequest(method,                                                  newUrl.toString(QUrl::RemoveScheme|QUrl::RemoveAuthority));            job->d->request.setURL(newUrl);            job->d->redirected = true;            return;        }    }    if (client)        client->didReceiveResponse(job->d->resourceHandle, response);}void QWebNetworkManager::data(QWebNetworkJob *job, const QByteArray &data){    Q_ASSERT(job->status() == QWebNetworkJob::JobStarted ||             job->status() == QWebNetworkJob::JobReceivingData);    job->setStatus(QWebNetworkJob::JobReceivingData);    ResourceHandleClient* client = 0;    if (job->d->resourceHandle) {        client = job->d->resourceHandle->client();        if (!client)            return;    } else {        return;    }    if (job->d->redirected)        return; // don't emit the "Document has moved here" type of HTML    DEBUG() << "receivedData" << job->d->request.url.path();    if (client)        client->didReceiveData(job->d->resourceHandle, data.constData(), data.length(), data.length() /*FixMe*/);}void QWebNetworkManager::finished(QWebNetworkJob *job, int errorCode){    Q_ASSERT(errorCode == 1 ||             job->status() == QWebNetworkJob::JobStarted ||             job->status() == QWebNetworkJob::JobReceivingData);    if (m_synchronousJobs.contains(job))        m_synchronousJobs.remove(job);    job->setStatus(QWebNetworkJob::JobFinished);    ResourceHandleClient* client = 0;    if (job->d->resourceHandle) {        client = job->d->resourceHandle->client();        if (!client)            return;    } else {        job->deref();        return;    }    DEBUG() << "receivedFinished" << errorCode << job->url();    if (job->d->redirected) {        job->d->redirected = false;        job->setStatus(QWebNetworkJob::JobRecreated);        job->d->interface->addJob(job);        return;    }    if (job->d->resourceHandle)        job->d->resourceHandle->getInternal()->m_job = 0;    if (client) {        if (errorCode) {            //FIXME: error setting error was removed from ResourceHandle            client->didFail(job->d->resourceHandle,                            ResourceError(job->d->request.url.host(), job->d->response.statusCode(),                                          job->d->request.url.toString(), job->d->errorString));        } else {            client->didFinishLoading(job->d->resourceHandle);        }    }    DEBUG() << "receivedFinished done" << job->d->request.url;    job->deref();}void QWebNetworkManager::addHttpJob(QWebNetworkJob *job){    HostInfo hostInfo(job->url());    WebCoreHttp *httpConnection = m_hostMapping.value(hostInfo);    if (!httpConnection) {        // #### fix custom ports        DEBUG() << "   new connection to" << hostInfo.host << hostInfo.port;        httpConnection = new WebCoreHttp(this, hostInfo);        QObject::connect(httpConnection, SIGNAL(connectionClosed(const WebCore::HostInfo&)),                         this, SLOT(httpConnectionClosed(const WebCore::HostInfo&)));        m_hostMapping[hostInfo] = httpConnection;    }    httpConnection->request(job);}void QWebNetworkManager::cancelHttpJob(QWebNetworkJob *job){    WebCoreHttp *httpConnection = m_hostMapping.value(job->url());    if (httpConnection)        httpConnection->cancel(job);}void QWebNetworkManager::httpConnectionClosed(const WebCore::HostInfo &info){    WebCoreHttp *connection = m_hostMapping.take(info);    connection->deleteLater();}void QWebNetworkInterfacePrivate::sendFileData(QWebNetworkJob* job, int statusCode, const QByteArray &data){    int error = statusCode >= 400 ? 1 : 0;    if (!job->cancelled()) {        QHttpResponseHeader response;        response.setStatusLine(statusCode);        response.setContentLength(data.length());        job->setResponse(response);        q->started(job);        if (!data.isEmpty())            q->data(job, data);    }    q->finished(job, error);}void QWebNetworkInterfacePrivate::parseDataUrl(QWebNetworkJob* job){    QByteArray data = job->url().toString().toLatin1();    //qDebug() << "handling data url:" << data;    ASSERT(data.startsWith("data:"));    // Here's the syntax of data URLs:    // dataurl    := "data:" [ mediatype ] [ ";base64" ] "," data    // mediatype  := [ type "/" subtype ] *( ";" parameter )    // data       := *urlchar    // parameter  := attribute "=" value    QByteArray header;    bool base64 = false;    int index = data.indexOf(',');    if (index != -1) {        header = data.mid(5, index - 5).toLower();        //qDebug() << "header=" << header;        data = data.mid(index+1);        //qDebug() << "data=" << data;        if (header.endsWith(";base64")) {            //qDebug() << "base64";            base64 = true;            header = header.left(header.length() - 7);            //qDebug() << "mime=" << header;        }    } else {        data = QByteArray();    }    if (base64) {        data = QByteArray::fromBase64(data);    } else {        data = decodePercentEncoding(data);    }    if (header.isEmpty())        header = "text/plain;charset=US-ASCII";    int statusCode = 200;    QHttpResponseHeader response;    response.setContentType(header);    response.setContentLength(data.size());    job->setResponse(response);    int error = statusCode >= 400 ? 1 : 0;    q->started(job);    if (!data.isEmpty())        q->data(job, data);    q->finished(job, error);}void QWebNetworkManager::queueStart(QWebNetworkJob* job){    Q_ASSERT(job->d);    QMutexLocker locker(&m_queueMutex);    job->ref();    m_pendingWork.append(new JobWork(job));    doScheduleWork();}void QWebNetworkManager::queueData(QWebNetworkJob* job, const QByteArray& data){    ASSERT(job->d);    QMutexLocker locker(&m_queueMutex);    job->ref();    m_pendingWork.append(new JobWork(job, data));    doScheduleWork();}void QWebNetworkManager::queueFinished(QWebNetworkJob* job, int errorCode){    Q_ASSERT(job->d);    QMutexLocker locker(&m_queueMutex);    job->ref();    m_pendingWork.append(new JobWork(job, errorCode));    doScheduleWork();}void QWebNetworkManager::doScheduleWork(){    if (!m_scheduledWork) {        m_scheduledWork = true;        emit scheduleWork();    }}/* * We will work on a copy of m_pendingWork. While dispatching m_pendingWork * new work will be added that will be handled at a later doWork call. doWork * will be called we set m_scheduledWork to false early in this method. */void QWebNetworkManager::doWork(){    m_queueMutex.lock();    m_scheduledWork = false;    bool hasSyncJobs = m_synchronousJobs.size();    const QHash<QWebNetworkJob*, int> syncJobs = m_synchronousJobs;    m_queueMutex.unlock();    foreach (JobWork* work, m_pendingWork) {        if (hasSyncJobs && !syncJobs.contains(work->job))            continue;        if (work->workType == JobWork::JobStarted)            started(work->job);        else if (work->workType == JobWork::JobData) {            // This job was not yet started            if (static_cast<int>(work->job->status()) < QWebNetworkJob::JobStarted)                continue;            data(work->job, work->data);        } else if (work->workType == JobWork::JobFinished) {            // This job was not yet started... we have no idea if data comes by...            // and it won't start in case of errors            if (static_cast<int>(work->job->status()) < QWebNetworkJob::JobStarted && work->errorCode != 1)                continue;            finished(work->job, work->errorCode);        }        m_queueMutex.lock();        m_pendingWork.removeAll(work);        m_queueMutex.unlock();        work->job->deref();        delete work;    }    m_queueMutex.lock();    if (hasSyncJobs && m_synchronousJobs.size() == 0)        doScheduleWork();    m_queueMutex.unlock();}/*!  \class QWebNetworkInterface  The QWebNetworkInterface class provides an abstraction layer for  WebKit's network interface.  It allows to completely replace or  extend the builtin network layer.

⌨️ 快捷键说明

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