title: C++ Upload large files over HTTP request, without reading whole file into the http request
body: <p>My program needs to upload huge files of 1GB,2GB,etc . I have tried using QHttpMultipart request &amp; other PUT &amp; POST requests on QNetworkAccessManager. Every time a QNetworkRequest is build, the application memory shoots <strong>up from 20MB to 1GB or 2GB as per the file</strong>, which leads to my application crashing (WINDOWS QT APP).</p>
  
  <pre><code>{
  
  QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
  
      QHttpPart textPart;
      textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\""));
  
      textPart.setBody("my text");
  
      QHttpPart imagePart;
      imagePart.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("image/jpeg"));
      imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));
  
      QFile *file = new QFile("LargeFile.zip");
  
      file-&gt;open(QIODevice::ReadOnly);
  
      imagePart.setBodyDevice(file); 
  
      file-&gt;setParent(multiPart); 
  
      multiPart-&gt;append(textPart);
      multiPart-&gt;append(imagePart);
  
      QUrl url("http://my.server.tld");
      QNetworkRequest request(url);
  
      quint64 contentlength = file-&gt;bytesAvailable();
      request.setHeader(QNetworkRequest::ContentLengthHeader,contentlength);
      request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute,true);
  
      QNetworkAccessManager manager;
      QNetworkReply *reply = manager.post(request, multiPart);
      multiPart-&gt;setParent(reply); 
  }
  </code></pre>
  
  <p><strong>HUGE increase in application memory equivalent to the huge file size at this point after POST request is fired,as whole file is read &amp; added into request body</strong></p>
  
  <p>What I found in C# is that, it's possible to upload huge files without increasing or reading the whole file. They keep on writing on the http request stream in chunks.</p>
  
  <p>In this code whatever may the File size be in GBs, application memory <strong>never</strong> goes beyond 40MB.</p>
  
  <p>public void upload(string url, string imagename, string imagepath, string finalType)</p>
  
  <pre><code>{
  
      try
      {
          FileStream fileStream = null;
          Stream rs = null;
          WebResponse lobjResponse = null;
          string lstrResponse = string.Empty;
          bool lblnIsConnected = true;
          long mlngBytesUploaded = 0;
          long llngContentLength = 0;
          long[] llngarrProgressStatusData = new long[2];
          string pstrResponse = string.Empty;
  
          long lintContentLenght = 0;
          string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
          byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
  
          string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
          string formitem = string.Format(formdataTemplate, "abc", "abc-val");
          byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
  
          string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
          string header = string.Format(headerTemplate, imagename, imagename, finalType);
          byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
  
          byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
  
          fileStream = new FileStream(imagepath, FileMode.Open, FileAccess.Read);
  
          lintContentLenght += boundarybytes.Length;
          lintContentLenght += formitembytes.Length;
          lintContentLenght += boundarybytes.Length;
          lintContentLenght += headerbytes.Length;
          lintContentLenght += fileStream.Length;
          lintContentLenght += trailer.Length;
  
          wr = (HttpWebRequest)WebRequest.Create(url);
          wr.AllowWriteStreamBuffering = false;
          wr.ContentType = "multipart/form-data; boundary=" + boundary;
          wr.ContentLength = lintContentLenght;
          wr.Method = "POST";
          wr.KeepAlive = true;
  
            using (rs = wr.GetRequestStream())
            {
                rs.Write(boundarybytes, 0, boundarybytes.Length);
                rs.Write(formitembytes, 0, formitembytes.Length);
                rs.Write(boundarybytes, 0, boundarybytes.Length);
                rs.Write(headerbytes, 0, headerbytes.Length);
  
                int bytesRead = 0;
                byte[] bufferSize = new byte[4096];
  
                llngContentLength = wr.ContentLength;
                llngarrProgressStatusData[0] = llngContentLength;
  
                            // BECAUSE OF READING FILE DATA in chunks &amp; WRITING IT to the STREAM. HERE WHOLE FILE ISN'T READ &amp; SET INTO REQUEST like in QHTTPMULTIPART request. Application memory remains constant in C# code.** 
                while ((bytesRead = fileStream.Read(bufferSize, 0, bufferSize.Length)) != 0) 
                {
  
                    if (!lblnIsConnected) break;
                      mlngBytesUploaded += bytesRead;
                    rs.Write(bufferSize, 0, bytesRead);
  
                    if (mlngBytesUploaded &gt; llngContentLength)
                        mlngBytesUploaded = llngContentLength;
  
                    llngarrProgressStatusData[1] = mlngBytesUploaded;
                    NotifyHTTPProgressBarUpdate(mlngBytesUploaded, llngContentLength);
                }
  
                fileStream.Close();
  
                if (lblnIsConnected)
                {
                    rs.Write(trailer, 0, trailer.Length);
                    rs.Close();
                }
            }
      }
  }
  </code></pre>
  
  <p>Sending file chunks is an option but currently I don't have that support on  my server.</p>
  
  <p>Can you please advice me on similar implementation of above C# code in QT to upload file in a stream over HTTP PUT/POST on a given URL. Is there a way to do the same in c++?</p>