void HtmlDownloader::doWork() { _num_threads->acquire(); if (_reply || _manager) return; // Perform get request QNetworkAccessManager* _manager = new QNetworkAccessManager(this); _reply = _manager->get(QNetworkRequest(_url)); if (!_reply) { if (_manager) { delete _manager; _manager = nullptr; } return; } // connect finish signal connect(_reply, SIGNAL(finished()), this, SLOT(download_finished()), Qt::DirectConnection); // connect progress signal connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)), Qt::DirectConnection); }
/* outgoingData is always 0 for Get and Head requests */ QNetworkReply* network_manager::createRequest(Operation op, const QNetworkRequest& req, QIODevice* outgoingData) { DBG_PRINTF(5, "createRequest for %s", req.url().toString().toLocal8Bit().constData()); if (op!=GetOperation) { // only GET is currently supported, see if HEAD should be return empty_network_reply(op, req); } const QUrl& url = req.url(); // the request refers to attached contents if (req.url().scheme() == "cid") { // refers to a MIME part that should be attached if (m_pmsg) { attachment* a = m_pmsg->attachments().get_by_content_id(req.url().path()); if (a!=NULL) { attachment_network_reply* reply = a->network_reply(req, this); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(download_error(QNetworkReply::NetworkError))); connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(download_progress(qint64,qint64))); connect(reply, SIGNAL(finished()), this, SLOT(download_finished())); return reply; } } return empty_network_reply(op, req); } else if (url.scheme()=="manitou" && (url.authority()=="xface" || url.authority()=="face")) { if (url.hasQueryItem("id") && url.hasQueryItem("o")) { QString headers = m_pmsg->get_headers(); bool id_ok, o_ok; uint id = url.queryItemValue("id").toUInt(&id_ok); int offset = url.queryItemValue("o").toInt(&o_ok); if (id_ok && o_ok && id == m_pmsg->get_id()) { int lf_pos = headers.indexOf('\n', offset); QString ascii_line; if (lf_pos>0) { ascii_line = headers.mid(offset, lf_pos-offset); } else { ascii_line = headers.mid(offset); } ascii_line.replace(" ", ""); int type = url.authority()=="face" ? 1:2; return new internal_img_network_reply(req, ascii_line, type, this); } } return empty_network_reply(op, req); } else if (req.url().scheme()=="style") { // internal scheme for styling contents return new internal_style_network_reply(req, m_body_style, this); } // the request refers to external contents if (m_ext_download_permitted) { // qDebug() << "op accepted for " << req.url().toString(); return QNetworkAccessManager::createRequest(op, req, outgoingData); } else { if (!m_ext_download_permission_asked) { // let know that contents were skipped so that the user can be // presented with the choice to fetch them or not emit external_contents_requested(); m_ext_download_permission_asked=true; } return empty_network_reply(op, req); } }
/* * The heart of the download system. It is called whenever there are new * sources, finished chunks, etc. * Merges complete chunks and tries to assign sources to inactive ones. If * there are more sources than chunks the chunks are split up. */ static void download_maintain (ASDownload *dl) { if (dl->state != DOWNLOAD_ACTIVE) { /* Must not happen. */ assert (dl->state == DOWNLOAD_ACTIVE); return; } #ifdef VERIFY_CONN_LIST /* Verify integrity of connection list */ verify_connections (dl); #endif /* Verify integrity of chunk list. */ if (!verify_chunks (dl)) { AS_ERR_1 ("Corrupted chunk list detected for \"%s\"", dl->filename); /* Fail download */ download_failed (dl); assert (0); return; } /* Clean up chunks. */ if (!consolidate_chunks (dl)) { AS_ERR_1 ("Consolidating chunks failed for \"%s\"", dl->filename); /* Fail download */ download_failed (dl); assert (0); return; } #ifdef CHUNK_DEBUG AS_HEAVY_DBG ("Chunk state after consolidating:"); dump_chunks (dl); AS_HEAVY_DBG ("Connection state after consolidating:"); dump_connections (dl); #endif /* Is the download complete? */ if (((ASDownChunk *)dl->chunks->data)->received == dl->size) { /* Download complete */ download_finished (dl); return; } /* Download not complete. Start more chunk downloads. */ if (!start_chunks (dl)) { /* This should be harmless. */ AS_WARN_1 ("Starting chunks failed for \"%s\"", dl->filename); } /* Check if we need more sources */ if (dl->conns == NULL) { /* TODO: start source search */ AS_ERR_1 ("FIXME: No more sources for \"%s\". Make me find more.", dl->filename); } }