title: QNetworkAccessManager: post http multipart from serial QIODevice
body: <p>I'm trying to use QNetworkAccessManager to upload http multiparts to a dedicated server.</p>
  
  <p>The multipart consists of a JSON part describing the data being uploaded.</p>
  
  <p>The data is read from a serial QIODevice, which encrypts the data.</p>
  
  <p>This is the code that creates the multipart request:</p>
  
  <pre><code>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-&gt;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-&gt;setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
  multiPart-&gt;append(filePart);
  
  QNetworkAccessManager netMgr;
  QScopedPointer&lt;QNetworkReply&gt; reply( netMgr.post(request, multiPart) );
  multiPart-&gt;setParent(reply.data()); // delete the multiPart with the reply
  </code></pre>
  
  <p>If the p_encDevice is an instance of QFile, that file gets uploaded just fine.</p>
  
  <p>If the specialised encrypting QIODevice is used (serial device) then all of the data is read from my custom device. however QNetworkAccessManager::post() doesn't complete (hangs).</p>
  
  <p>I read in the documentation of <a href="http://qt-project.org/doc/qt-4.8/qhttppart.html#setBodyDevice" rel="nofollow">QHttpPart</a> that:</p>
  
  <blockquote>
    <p>if device is sequential (e.g. sockets, but not files),
    QNetworkAccessManager::post() should be called after device has
    emitted finished().</p>
  </blockquote>
  
  <p>Unfortunately I don't know how do that.</p>
  
  <p>Please advise.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>QIODevice doesn't have finished() slot at all. What's more, reading from my custom IODevice doesn't happen at all if QNetworkAccessManager::post() is not called and therefore the device wouldn't be able to emit such an event. (Catch 22?)</p>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>It seems that QNAM does not work with sequential devices at all. See <a href="http://qt-project.org/forums/viewthread/25317/" rel="nofollow">discussion on qt-project</a>.</p>
  
  <p><strong>EDIT 3:</strong></p>
  
  <p>I managed to "fool" QNAM to make it think that it is reading from non-sequential devices, but seek and reset functions prevent seeking. This will work until QNAM will actually try to seek.</p>
  
  <pre><code>bool AesDevice::isSequential() const
  {
      return false;
  }
  
  bool AesDevice::reset()
  {
      if (this-&gt;pos() != 0) {
          return false;
      }
      return QIODevice::reset();
  }
  
  bool AesDevice::seek(qint64 pos)
  {
      if (this-&gt;pos() != pos) {
          return false;
      }
      return QIODevice::seek(pos);
  }
  </code></pre>