Sto tentando di utilizzare QNetworkAccessManager per caricare http multiparte su un server dedicato.QNetworkAccessManager: post http multipart da seriale QIODevice
Il multipart è costituito da una parte JSON che descrive i dati caricati.
I dati vengono letti da un dispositivo QIODial seriale, che crittografa i dati.
Questo è il codice che crea la domanda più parti:
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart metaPart;
metaPart.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
metaPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"metadata\""));
metaPart.setBody(meta.toJson());
multiPart->append(metaPart);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(fileFormat));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\""));
filePart.setBodyDevice(p_encDevice);
p_encDevice->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(filePart);
QNetworkAccessManager netMgr;
QScopedPointer<QNetworkReply> reply(netMgr.post(request, multiPart));
multiPart->setParent(reply.data()); // delete the multiPart with the reply
Se il p_encDevice è un'istanza di qfile, che file viene caricato bene.
Se viene utilizzato il dispositivo QIODisk di crittografia specializzato (dispositivo seriale), tutti i dati vengono letti dal mio dispositivo personalizzato. tuttavia QNetworkAccessManager :: post() non viene completato (si blocca).
ho letto nella documentazione di QHttpPart che:
se il dispositivo è sequenziale (ad esempio, prese, ma non i file), QNetworkAccessManager :: post() deve essere chiamato dopo che il dispositivo ha emesso finito() .
Purtroppo non so come farlo.
Si prega di avvisare.
EDIT:
QIODevice non ha fessura finito() affatto. Inoltre, la lettura dal mio IODevice personalizzato non si verifica affatto se QNetworkAccessManager :: post() non viene chiamato e quindi il dispositivo non sarebbe in grado di emettere tale evento. (Catch 22?)
EDIT 2:
Sembra che QNAM non funziona con i dispositivi sequenziali a tutti. Vedi discussion on qt-project.
EDIT 3:
sono riuscito a "ingannare" QNAM per farlo pensare che sta leggendo da dispositivi non sequenziali, ma cercare e ripristinare le funzioni impediscono alla ricerca. Questo funzionerà fino a quando QNAM cercherà effettivamente di cercare.
bool AesDevice::isSequential() const
{
return false;
}
bool AesDevice::reset()
{
if (this->pos() != 0) {
return false;
}
return QIODevice::reset();
}
bool AesDevice::seek(qint64 pos)
{
if (this->pos() != pos) {
return false;
}
return QIODevice::seek(pos);
}
Penso che il segnale appropriato sia 'QIODevice :: readChannelFinished()'. Fondamentalmente 'QIODevice :: bytesAvailable()' deve restituire il valore corretto affinché funzioni. –
Hai risolto il problema da allora, matejk? – lpapp
Sono riuscito a risolverlo, ma non in modo pulito. Vedi il mio commento qui sotto. – matejk