Esempio n. 1
0
bool KWebPage::handleReply(QNetworkReply* reply, QString* contentType, KIO::MetaData* metaData)
{
    // Reply url...
    const KUrl replyUrl (reply->url());

    // Get suggested file name...
    const KIO::MetaData& data = reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap();
    const QString suggestedFileName = data.value(QL1S("content-disposition-filename"));
    if (metaData) {
        *metaData = data;
    }

    // Get the mime-type...
    QString mimeType;
    extractMimeType(reply, mimeType);
    if (contentType) {
        *contentType = mimeType;
    }

    // Let the calling function deal with handling empty or inode/* mimetypes...
    if (mimeType.isEmpty() || mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive)) {
        return false;
    }

    // Convert executable text files to plain text...
    if (KParts::BrowserRun::isTextExecutable(mimeType))
        mimeType = QL1S("text/plain");

    //kDebug(800) << "Content-disposition:" << suggestedFileName;
    //kDebug(800) << "Got unsupported content of type:" << mimeType << "URL:" << replyUrl;
    //kDebug(800) << "Error code:" << reply->error() << reply->errorString();

    if (isReplyStatusOk(reply)) {
        while (true) {
            KParts::BrowserOpenOrSaveQuestion::Result result;
            KParts::BrowserOpenOrSaveQuestion dlg(d->windowWidget(), replyUrl, mimeType);
            dlg.setSuggestedFileName(suggestedFileName);
            dlg.setFeatures(KParts::BrowserOpenOrSaveQuestion::ServiceSelection);
            result = dlg.askOpenOrSave();

            switch (result) {
            case KParts::BrowserOpenOrSaveQuestion::Open:
                // Handle Post operations that return content...
                if (reply->operation() == QNetworkAccessManager::PostOperation) {
                    d->mimeType = mimeType;
                    QFileInfo finfo (suggestedFileName.isEmpty() ? replyUrl.fileName() : suggestedFileName);
                    KTemporaryFile tempFile;
                    tempFile.setSuffix(QL1C('.') + finfo.suffix());
                    tempFile.setAutoRemove(false);
                    tempFile.open();
                    KUrl destUrl;
                    destUrl.setPath(tempFile.fileName());
                    KIO::Job *job = KIO::file_copy(replyUrl, destUrl, 0600, KIO::Overwrite);
                    job->ui()->setWindow(d->windowWidget());
                    job->ui()->setAutoErrorHandlingEnabled(true);
                    connect(job, SIGNAL(result(KJob*)),
                            this, SLOT(_k_copyResultToTempFile(KJob*)));
                    return true;
                }

                // Ask before running any executables...
                if (KParts::BrowserRun::allowExecution(mimeType, replyUrl)) {
                    KService::Ptr offer = dlg.selectedService();
                    // HACK: The check below is necessary to break an infinite
                    // recursion that occurs whenever this function is called as a result
                    // of receiving content that can be rendered by the app using this engine.
                    // For example a text/html header that containing a content-disposition
                    // header is received by the app using this class.
                    if (isMimeTypeAssociatedWithSelf(offer)) {
                        reloadRequestWithoutDisposition(reply);
                    } else {
                        KUrl::List list;
                        list.append(replyUrl);
                        bool success = false;
                        // kDebug(800) << "Suggested file name:" << suggestedFileName;
                        if (offer) {
                            success = KRun::run(*offer, list, d->windowWidget() , false, suggestedFileName);
                        } else {
                            success = KRun::displayOpenWithDialog(list, d->windowWidget(), false, suggestedFileName);
                            if (!success)
                                break;
                        }
                        // For non KIO apps and cancelled Open With dialog, remove slave on hold.
                        if (!success || (offer && !offer->categories().contains(QL1S("KDE")))) {
                            KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
                        }
                    }
                    return true;
                }
                // TODO: Instead of silently failing when allowExecution fails, notify
                // the user why the requested action cannot be fulfilled...
                return false;
            case KParts::BrowserOpenOrSaveQuestion::Save:
                // Do not download local files...
                if (!replyUrl.isLocalFile()) {
                    QString downloadCmd (reply->property("DownloadManagerExe").toString());
                    if (!downloadCmd.isEmpty()) {
                        downloadCmd += QLatin1Char(' ');
                        downloadCmd += KShell::quoteArg(replyUrl.url());
                        if (!suggestedFileName.isEmpty()) {
                            downloadCmd += QLatin1Char(' ');
                            downloadCmd += KShell::quoteArg(suggestedFileName);
                        }
                        // kDebug(800) << "download command:" << downloadCmd;
                        if (KRun::runCommand(downloadCmd, view()))
                            return true;
                    }
                    if (!downloadResource(replyUrl, suggestedFileName, d->windowWidget()))
                        break;
                }
                return true;
            case KParts::BrowserOpenOrSaveQuestion::Cancel:
            default:
                KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
                return true;
            }
        }
    } else {
Esempio n. 2
0
void WebPage::handleUnsupportedContent(QNetworkReply *reply)
{
    Q_ASSERT(reply);

    // Put the job on hold...
#if KDE_IS_VERSION( 4, 5, 96)
    kDebug() << "PUT REPLY ON HOLD...";
    KIO::Integration::AccessManager::putReplyOnHold(reply);
#else
    reply->abort();
#endif

    // This is probably needed just in ONE stupid case..
    if (_protHandler.postHandling(reply->request(), mainFrame()))
    {
        kDebug() << "POST HANDLING the unsupported...";
        return;
    }

    if (reply->error() != QNetworkReply::NoError)
        return;

    // get reply url...
    KUrl replyUrl = reply->url();

    bool isLocal = replyUrl.isLocalFile();
    if(isLocal && KProtocolInfo::isKnownProtocol(replyUrl))
    {
        kDebug() << "WARNING: launching a new app...";
        new KRun(replyUrl, rApp->mainWindow());  // No need to delete KRun, it autodeletes itself
        return;
    }

    // Get suggested file name...
    extractSuggestedFileName(reply, _suggestedFileName);

    // Get mimeType...
    extractMimeType(reply, _mimeType);

    // Convert executable text files to plain text...
    if (KParts::BrowserRun::isTextExecutable(_mimeType))
        _mimeType = QL1S("text/plain");

    kDebug() << "Detected MimeType = " << _mimeType;
    kDebug() << "Suggested File Name = " << _suggestedFileName;
    // ------------------------------------------------

    KService::Ptr appService = KMimeTypeTrader::self()->preferredService(_mimeType);

    if (appService.isNull())  // no service can handle this. We can just download it..
    {
        kDebug() << "no service can handle this. We can just download it..";

        isLocal
        ? KMessageBox::sorry(view(), i18n("No service can handle this file."))
        : downloadReply(reply, _suggestedFileName);

        return;
    }

    if (!isLocal)
    {
        KParts::BrowserOpenOrSaveQuestion dlg(rApp->mainWindow(), replyUrl, _mimeType);
        if (!_suggestedFileName.isEmpty())
            dlg.setSuggestedFileName(_suggestedFileName);

        switch (dlg.askEmbedOrSave())
        {
        case KParts::BrowserOpenOrSaveQuestion::Save:
            kDebug() << "user choice: no services, just download!";
            downloadReply(reply, _suggestedFileName);
            return;

        case KParts::BrowserOpenOrSaveQuestion::Cancel:
            return;

        default: // non extant case
            break;
        }
    }

    // Handle Post operations that return content...
    if (reply->operation() == QNetworkAccessManager::PostOperation)
    {
        kDebug() << "POST OPERATION: downloading file...";
        QFileInfo finfo(_suggestedFileName.isEmpty() ? _loadingUrl.fileName() : _suggestedFileName);
        KTemporaryFile tempFile;
        tempFile.setSuffix(QL1C('.') + finfo.suffix());
        tempFile.setAutoRemove(false);
        tempFile.open();
        KUrl destUrl;
        destUrl.setPath(tempFile.fileName());
        kDebug() << "First save content to" << destUrl;
        KIO::Job *job = KIO::file_copy(_loadingUrl, destUrl, 0600, KIO::Overwrite);
        job->ui()->setWindow(rApp->mainWindow());
        connect(job, SIGNAL(result(KJob *)), this, SLOT(copyToTempFileResult(KJob*)));
        return;
    }