Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Fail to upload file using QHttpMultipart to a nodejs server with multer



  • Hi Qt Community! I am actually experiencing a problem while trying to use QHttpMultipart to upload the file to a nodejs server using express and Multer. I am sure that the server is running properly, the problem might be on the QHttpMultipart side. Here is the code for my nodejs server and the QHttpMultipart upload part.
    node server:

    const express = require('express');
    const sqlite3 = require('sqlite3').verbose();
    const multer = require('multer');
    const app = express();
    const upload = multer({ dest: './tmp/' })
    app.use(express.static('.'));
    
    let db = new sqlite3.Database('./resources/files.sqlite');
    
    app.get('/',(req, res)=>{
        res.status(200).send("<form action=\"/upload\" enctype=\"multipart/form-data\" method=\"post\">\n" +
            "    <div class=\"form-group\">\n" +
            "        <input type=\"file\" class=\"form-control-file\" name=\"zip\">\n" +
            "        <input type=\"submit\" value=\"Get me the stats!\" class=\"btn btn-default\">\n" +
            "    </div>\n" +
            "</form>")
    })
    
    app.get('/pcbs',(req,res) => {
        db.all("SELECT id, name, png, gerber, drill FROM PCBs LIMIT 30",[], (err, rows)=>{
            if (err) throw err;
            res.json({
                "pcbs": rows
            })
        })
    })
    
    app.post('/upload',upload.single("zip"),(req,res,next)=>{
            console.log(req);
            res.status(200).send("successfully uploaded the file!")
    });
    
    const PORT = 4200;
    app.listen(PORT, ()=>{
        console.log(`App running on port ${PORT}`);
    });
    

    Here is the qt code:

    QString file_path = QFileDialog::getOpenFileName(this, "Choose zip you want to upload",QDir::currentPath(),"Compressed File (*.zip)");
        qDebug() << file_path;
        QNetworkRequest upload_request;
        upload_request.setUrl(urlBase + "upload");
        QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    
        QHttpPart zipPart;
        zipPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/zip"));
        zipPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"zip\""));
        QFile *file = new QFile(file_path);
        file->open(QIODevice::ReadOnly);
        zipPart.setBodyDevice(file);
        file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
    
        multiPart->append(zipPart);
    
        QNetworkAccessManager *upload_manager = new QNetworkAccessManager(this);
    
        QNetworkReply *reply = upload_manager->post(upload_request, multiPart);
        connect(upload_manager,&QNetworkAccessManager::finished,[this, reply,file](){
            QString data = (QString)reply->readAll();
            QJsonDocument jsonResponse = QJsonDocument::fromJson(data.toUtf8());
            QJsonObject jsonObject = jsonResponse.object();
            qDebug() << jsonObject["message"].toString();
            file->close();
        });
    

    Any advice would be helpful! Thank you very much!



  • @never0lie
    Looks like the only difference in the file part is the Content-Disposition header.
    As you can see, the one from your successful upload is QVariant("form-data; name=\"zip\"; filename=\"3-half-bridges-board_drill.zip\"").
    I'm not sure if this is the key part (to have a filename?) but you can start with that.



  • In the beginning, I mentioned that the server is working properly. Here is the HTTP request printed from the node server when the file upload was working properly. I would post the request when using QHttpMultipart in a second post too due to character limit. I think the big difference is at the end around the body part:

    IncomingMessage {
      _readableState: ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: [],
        flowing: false,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: false,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        errorEmitted: false,
        emitClose: true,
        autoDestroy: false,
        destroyed: false,
        errored: null,
        closed: false,
        closeEmitted: false,
        defaultEncoding: 'utf8',
        awaitDrainWriters: null,
        multiAwaitDrain: false,
        readingMore: false,
        decoder: null,
        encoding: null,
        [Symbol(kPaused)]: true
      },
      _events: [Object: null prototype] {
        end: [Function: clearRequestTimeout],
        readable: [Function: bound ]
      },
      _eventsCount: 2,
      _maxListeners: undefined,
      socket: <ref *1> Socket {
        connecting: false,
        _hadError: false,
        _parent: null,
        _host: null,
        _readableState: ReadableState {
          objectMode: false,
          highWaterMark: 16384,
          buffer: BufferList { head: null, tail: null, length: 0 },
          length: 0,
          pipes: [],
          flowing: true,
          ended: false,
          endEmitted: false,
          reading: true,
          sync: false,
          needReadable: true,
          emittedReadable: false,
          readableListening: false,
          resumeScheduled: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          destroyed: false,
          errored: null,
          closed: false,
          closeEmitted: false,
          defaultEncoding: 'utf8',
          awaitDrainWriters: null,
          multiAwaitDrain: false,
          readingMore: false,
          decoder: null,
          encoding: null,
          [Symbol(kPaused)]: false
        },
        _events: [Object: null prototype] {
          end: [Array],
          timeout: [Function: socketOnTimeout],
          data: [Function: bound socketOnData],
          error: [Function: socketOnError],
          close: [Array],
          drain: [Function: bound socketOnDrain],
          resume: [Function: onSocketResume],
          pause: [Function: onSocketPause]
        },
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: WritableState {
          objectMode: false,
          highWaterMark: 16384,
          finalCalled: false,
          needDrain: false,
          ending: false,
          ended: false,
          finished: false,
          destroyed: false,
          decodeStrings: false,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: true,
          bufferProcessing: false,
          onwrite: [Function: bound onwrite],
          writecb: null,
          writelen: 0,
          afterWriteTickInfo: null,
          buffered: [],
          bufferedIndex: 0,
          allBuffers: true,
          allNoop: true,
          pendingcb: 0,
          prefinished: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          errored: null,
          closed: false,
          closeEmitted: false
        },
        allowHalfOpen: true,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        _server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        parser: HTTPParser {
          '0': [Function: bound setRequestTimeout],
          '1': [Function: parserOnHeaders],
          '2': [Function: parserOnHeadersComplete],
          '3': [Function: parserOnBody],
          '4': [Function: parserOnMessageComplete],
          '5': [Function: bound onParserExecute],
          '6': [Function: bound onParserTimeout],
          _headers: [],
          _url: '',
          socket: [Circular *1],
          incoming: [Circular *2],
          outgoing: null,
          maxHeaderPairs: 2000,
          _consumed: true,
          onIncoming: [Function: bound parserOnIncoming],
          [Symbol(resource_symbol)]: [HTTPServerAsyncResource]
        },
        on: [Function: socketListenerWrap],
        addListener: [Function: socketListenerWrap],
        prependListener: [Function: socketListenerWrap],
        _paused: false,
        _httpMessage: ServerResponse {
          _events: [Object: null prototype],
          _eventsCount: 1,
          _maxListeners: undefined,
          outputData: [],
          outputSize: 0,
          writable: true,
          destroyed: false,
          _last: false,
          chunkedEncoding: false,
          shouldKeepAlive: true,
          _defaultKeepAlive: true,
          useChunkedEncodingByDefault: true,
          sendDate: true,
          _removedConnection: false,
          _removedContLen: false,
          _removedTE: false,
          _contentLength: null,
          _hasBody: true,
          _trailer: '',
          finished: false,
          _headerSent: false,
          socket: [Circular *1],
          _header: null,
          _keepAliveTimeout: 5000,
          _onPendingData: [Function: bound updateOutgoingData],
          _sent100: false,
          _expect_continue: false,
          req: [Circular *2],
          locals: [Object: null prototype] {},
          [Symbol(kCapture)]: false,
          [Symbol(kNeedDrain)]: false,
          [Symbol(corked)]: 0,
          [Symbol(kOutHeaders)]: [Object: null prototype]
        },
        [Symbol(async_id_symbol)]: 10,
        [Symbol(kHandle)]: TCP {
          reading: true,
          onconnection: null,
          _consumed: true,
          [Symbol(owner_symbol)]: [Circular *1]
        },
        [Symbol(kSetNoDelay)]: false,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBuffer)]: null,
        [Symbol(kBufferCb)]: null,
        [Symbol(kBufferGen)]: null,
        [Symbol(kCapture)]: false,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(RequestTimeout)]: undefined
      },
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: {
        host: 'localhost:4200',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0',
        accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
        'accept-language': 'en-US,en;q=0.5',
        'accept-encoding': 'gzip, deflate',
        'content-type': 'multipart/form-data; boundary=---------------------------385258764023582583331996931452',
        'content-length': '1097',
        origin: 'http://localhost:4200',
        connection: 'keep-alive',
        referer: 'http://localhost:4200/',
        cookie: 'CSRF-Token-H6YUN=hAqmz6osDkzJ3QpLXETxettncrWx2siE; Webstorm-a8c8e774=5c7fc9b9-8e97-409a-9303-9bd6c54e8e00',
        'upgrade-insecure-requests': '1'
      },
      rawHeaders: [
        'Host',
        'localhost:4200',
        'User-Agent',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0',
        'Accept',
        'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
        'Accept-Language',
        'en-US,en;q=0.5',
        'Accept-Encoding',
        'gzip, deflate',
        'Content-Type',
        'multipart/form-data; boundary=---------------------------385258764023582583331996931452',
        'Content-Length',
        '1097',
        'Origin',
        'http://localhost:4200',
        'Connection',
        'keep-alive',
        'Referer',
        'http://localhost:4200/',
        'Cookie',
        'CSRF-Token-H6YUN=hAqmz6osDkzJ3QpLXETxettncrWx2siE; Webstorm-a8c8e774=5c7fc9b9-8e97-409a-9303-9bd6c54e8e00',
        'Upgrade-Insecure-Requests',
        '1'
      ],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '/upload',
      method: 'POST',
      statusCode: null,
      statusMessage: null,
      client: <ref *1> Socket {
        connecting: false,
        _hadError: false,
        _parent: null,
        _host: null,
        _readableState: ReadableState {
          objectMode: false,
          highWaterMark: 16384,
          buffer: BufferList { head: null, tail: null, length: 0 },
          length: 0,
          pipes: [],
          flowing: true,
          ended: false,
          endEmitted: false,
          reading: true,
          sync: false,
          needReadable: true,
          emittedReadable: false,
          readableListening: false,
          resumeScheduled: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          destroyed: false,
          errored: null,
          closed: false,
          closeEmitted: false,
          defaultEncoding: 'utf8',
          awaitDrainWriters: null,
          multiAwaitDrain: false,
          readingMore: false,
          decoder: null,
          encoding: null,
          [Symbol(kPaused)]: false
        },
        _events: [Object: null prototype] {
          end: [Array],
          timeout: [Function: socketOnTimeout],
          data: [Function: bound socketOnData],
          error: [Function: socketOnError],
          close: [Array],
          drain: [Function: bound socketOnDrain],
          resume: [Function: onSocketResume],
          pause: [Function: onSocketPause]
        },
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: WritableState {
          objectMode: false,
          highWaterMark: 16384,
          finalCalled: false,
          needDrain: false,
          ending: false,
          ended: false,
          finished: false,
          destroyed: false,
          decodeStrings: false,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: true,
          bufferProcessing: false,
          onwrite: [Function: bound onwrite],
          writecb: null,
          writelen: 0,
          afterWriteTickInfo: null,
          buffered: [],
          bufferedIndex: 0,
          allBuffers: true,
          allNoop: true,
          pendingcb: 0,
          prefinished: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          errored: null,
          closed: false,
          closeEmitted: false
        },
        allowHalfOpen: true,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        _server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        parser: HTTPParser {
          '0': [Function: bound setRequestTimeout],
          '1': [Function: parserOnHeaders],
          '2': [Function: parserOnHeadersComplete],
          '3': [Function: parserOnBody],
          '4': [Function: parserOnMessageComplete],
          '5': [Function: bound onParserExecute],
          '6': [Function: bound onParserTimeout],
          _headers: [],
          _url: '',
          socket: [Circular *1],
          incoming: [Circular *2],
          outgoing: null,
          maxHeaderPairs: 2000,
          _consumed: true,
          onIncoming: [Function: bound parserOnIncoming],
          [Symbol(resource_symbol)]: [HTTPServerAsyncResource]
        },
        on: [Function: socketListenerWrap],
        addListener: [Function: socketListenerWrap],
        prependListener: [Function: socketListenerWrap],
        _paused: false,
        _httpMessage: ServerResponse {
          _events: [Object: null prototype],
          _eventsCount: 1,
          _maxListeners: undefined,
          outputData: [],
          outputSize: 0,
          writable: true,
          destroyed: false,
          _last: false,
          chunkedEncoding: false,
          shouldKeepAlive: true,
          _defaultKeepAlive: true,
          useChunkedEncodingByDefault: true,
          sendDate: true,
          _removedConnection: false,
          _removedContLen: false,
          _removedTE: false,
          _contentLength: null,
          _hasBody: true,
          _trailer: '',
          finished: false,
          _headerSent: false,
          socket: [Circular *1],
          _header: null,
          _keepAliveTimeout: 5000,
          _onPendingData: [Function: bound updateOutgoingData],
          _sent100: false,
          _expect_continue: false,
          req: [Circular *2],
          locals: [Object: null prototype] {},
          [Symbol(kCapture)]: false,
          [Symbol(kNeedDrain)]: false,
          [Symbol(corked)]: 0,
          [Symbol(kOutHeaders)]: [Object: null prototype]
        },
        [Symbol(async_id_symbol)]: 10,
        [Symbol(kHandle)]: TCP {
          reading: true,
          onconnection: null,
          _consumed: true,
          [Symbol(owner_symbol)]: [Circular *1]
        },
        [Symbol(kSetNoDelay)]: false,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBuffer)]: null,
        [Symbol(kBufferCb)]: null,
        [Symbol(kBufferGen)]: null,
        [Symbol(kCapture)]: false,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(RequestTimeout)]: undefined
      },
      _consuming: true,
      _dumped: false,
      next: [Function: next],
      baseUrl: '',
      originalUrl: '/upload',
      _parsedUrl: Url {
        protocol: null,
        slashes: null,
        auth: null,
        host: null,
        port: null,
        hostname: null,
        hash: null,
        search: null,
        query: null,
        pathname: '/upload',
        path: '/upload',
        href: '/upload',
        _raw: '/upload'
      },
      params: {},
      query: {},
      res: <ref *3> ServerResponse {
        _events: [Object: null prototype] { finish: [Function: bound resOnFinish] },
        _eventsCount: 1,
        _maxListeners: undefined,
        outputData: [],
        outputSize: 0,
        writable: true,
        destroyed: false,
        _last: false,
        chunkedEncoding: false,
        shouldKeepAlive: true,
        _defaultKeepAlive: true,
        useChunkedEncodingByDefault: true,
        sendDate: true,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: null,
        _hasBody: true,
        _trailer: '',
        finished: false,
        _headerSent: false,
        socket: <ref *1> Socket {
          connecting: false,
          _hadError: false,
          _parent: null,
          _host: null,
          _readableState: [ReadableState],
          _events: [Object: null prototype],
          _eventsCount: 8,
          _maxListeners: undefined,
          _writableState: [WritableState],
          allowHalfOpen: true,
          _sockname: null,
          _pendingData: null,
          _pendingEncoding: '',
          server: [Server],
          _server: [Server],
          parser: [HTTPParser],
          on: [Function: socketListenerWrap],
          addListener: [Function: socketListenerWrap],
          prependListener: [Function: socketListenerWrap],
          _paused: false,
          _httpMessage: [Circular *3],
          [Symbol(async_id_symbol)]: 10,
          [Symbol(kHandle)]: [TCP],
          [Symbol(kSetNoDelay)]: false,
          [Symbol(lastWriteQueueSize)]: 0,
          [Symbol(timeout)]: null,
          [Symbol(kBuffer)]: null,
          [Symbol(kBufferCb)]: null,
          [Symbol(kBufferGen)]: null,
          [Symbol(kCapture)]: false,
          [Symbol(kBytesRead)]: 0,
          [Symbol(kBytesWritten)]: 0,
          [Symbol(RequestTimeout)]: undefined
        },
        _header: null,
        _keepAliveTimeout: 5000,
        _onPendingData: [Function: bound updateOutgoingData],
        _sent100: false,
        _expect_continue: false,
        req: [Circular *2],
        locals: [Object: null prototype] {},
        [Symbol(kCapture)]: false,
        [Symbol(kNeedDrain)]: false,
        [Symbol(corked)]: 0,
        [Symbol(kOutHeaders)]: [Object: null prototype] { 'x-powered-by': [Array] }
      },
      route: Route {
        path: '/upload',
        stack: [ [Layer], [Layer] ],
        methods: { post: true }
      },
      body: [Object: null prototype] {},
      file: {
        fieldname: 'zip',
        originalname: '3-half-bridges-board_drill.zip',
        encoding: '7bit',
        mimetype: 'application/zip',
        destination: './tmp/',
        filename: '13289ddcca83407a7770faeda5bd62a4',
        path: 'tmp/13289ddcca83407a7770faeda5bd62a4',
        size: 851
      },
      [Symbol(kCapture)]: false,
      [Symbol(RequestTimeout)]: undefined
    }
    


  • here is the request printed from node when I use QHttpMultipart:

    IncomingMessage {
      _readableState: ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: [],
        flowing: false,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: false,
        needReadable: false,
        emittedReadable: false,
        readableListening: true,
        resumeScheduled: false,
        errorEmitted: false,
        emitClose: true,
        autoDestroy: false,
        destroyed: false,
        errored: null,
        closed: false,
        closeEmitted: false,
        defaultEncoding: 'utf8',
        awaitDrainWriters: null,
        multiAwaitDrain: false,
        readingMore: false,
        decoder: null,
        encoding: null,
        [Symbol(kPaused)]: true
      },
      _events: [Object: null prototype] {
        end: [Function: clearRequestTimeout],
        readable: [Function: bound ]
      },
      _eventsCount: 2,
      _maxListeners: undefined,
      socket: <ref *1> Socket {
        connecting: false,
        _hadError: false,
        _parent: null,
        _host: null,
        _readableState: ReadableState {
          objectMode: false,
          highWaterMark: 16384,
          buffer: BufferList { head: null, tail: null, length: 0 },
          length: 0,
          pipes: [],
          flowing: true,
          ended: false,
          endEmitted: false,
          reading: true,
          sync: false,
          needReadable: true,
          emittedReadable: false,
          readableListening: false,
          resumeScheduled: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          destroyed: false,
          errored: null,
          closed: false,
          closeEmitted: false,
          defaultEncoding: 'utf8',
          awaitDrainWriters: null,
          multiAwaitDrain: false,
          readingMore: false,
          decoder: null,
          encoding: null,
          [Symbol(kPaused)]: false
        },
        _events: [Object: null prototype] {
          end: [Array],
          timeout: [Function: socketOnTimeout],
          data: [Function: bound socketOnData],
          error: [Function: socketOnError],
          close: [Array],
          drain: [Function: bound socketOnDrain],
          resume: [Function: onSocketResume],
          pause: [Function: onSocketPause]
        },
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: WritableState {
          objectMode: false,
          highWaterMark: 16384,
          finalCalled: false,
          needDrain: false,
          ending: false,
          ended: false,
          finished: false,
          destroyed: false,
          decodeStrings: false,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: true,
          bufferProcessing: false,
          onwrite: [Function: bound onwrite],
          writecb: null,
          writelen: 0,
          afterWriteTickInfo: null,
          buffered: [],
          bufferedIndex: 0,
          allBuffers: true,
          allNoop: true,
          pendingcb: 0,
          prefinished: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          errored: null,
          closed: false,
          closeEmitted: false
        },
        allowHalfOpen: true,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        _server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        parser: HTTPParser {
          '0': [Function: bound setRequestTimeout],
          '1': [Function: parserOnHeaders],
          '2': [Function: parserOnHeadersComplete],
          '3': [Function: parserOnBody],
          '4': [Function: parserOnMessageComplete],
          '5': [Function: bound onParserExecute],
          '6': [Function: bound onParserTimeout],
          _headers: [],
          _url: '',
          socket: [Circular *1],
          incoming: [Circular *2],
          outgoing: null,
          maxHeaderPairs: 2000,
          _consumed: true,
          onIncoming: [Function: bound parserOnIncoming],
          [Symbol(resource_symbol)]: [HTTPServerAsyncResource]
        },
        on: [Function: socketListenerWrap],
        addListener: [Function: socketListenerWrap],
        prependListener: [Function: socketListenerWrap],
        _paused: false,
        _httpMessage: ServerResponse {
          _events: [Object: null prototype],
          _eventsCount: 1,
          _maxListeners: undefined,
          outputData: [],
          outputSize: 0,
          writable: true,
          destroyed: false,
          _last: false,
          chunkedEncoding: false,
          shouldKeepAlive: true,
          _defaultKeepAlive: true,
          useChunkedEncodingByDefault: true,
          sendDate: true,
          _removedConnection: false,
          _removedContLen: false,
          _removedTE: false,
          _contentLength: null,
          _hasBody: true,
          _trailer: '',
          finished: false,
          _headerSent: false,
          socket: [Circular *1],
          _header: null,
          _keepAliveTimeout: 5000,
          _onPendingData: [Function: bound updateOutgoingData],
          _sent100: false,
          _expect_continue: false,
          req: [Circular *2],
          locals: [Object: null prototype] {},
          [Symbol(kCapture)]: false,
          [Symbol(kNeedDrain)]: false,
          [Symbol(corked)]: 0,
          [Symbol(kOutHeaders)]: [Object: null prototype]
        },
        [Symbol(async_id_symbol)]: 10,
        [Symbol(kHandle)]: TCP {
          reading: true,
          onconnection: null,
          _consumed: true,
          [Symbol(owner_symbol)]: [Circular *1]
        },
        [Symbol(kSetNoDelay)]: false,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBuffer)]: null,
        [Symbol(kBufferCb)]: null,
        [Symbol(kBufferGen)]: null,
        [Symbol(kCapture)]: false,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(RequestTimeout)]: undefined
      },
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: {
        host: 'localhost:4200',
        'content-type': 'multipart/form-data; boundary="boundary_.oOo._gNCCVxxFwI3s+FNvVPGkoG7tAe6t6s+Y"',
        'mime-version': '1.0',
        'content-length': '1034',
        connection: 'Keep-Alive',
        'accept-encoding': 'gzip, deflate',
        'accept-language': 'en-US,*',
        'user-agent': 'Mozilla/5.0'
      },
      rawHeaders: [
        'Host',
        'localhost:4200',
        'Content-Type',
        'multipart/form-data; boundary="boundary_.oOo._gNCCVxxFwI3s+FNvVPGkoG7tAe6t6s+Y"',
        'MIME-Version',
        '1.0',
        'Content-Length',
        '1034',
        'Connection',
        'Keep-Alive',
        'Accept-Encoding',
        'gzip, deflate',
        'Accept-Language',
        'en-US,*',
        'User-Agent',
        'Mozilla/5.0'
      ],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '/upload',
      method: 'POST',
      statusCode: null,
      statusMessage: null,
      client: <ref *1> Socket {
        connecting: false,
        _hadError: false,
        _parent: null,
        _host: null,
        _readableState: ReadableState {
          objectMode: false,
          highWaterMark: 16384,
          buffer: BufferList { head: null, tail: null, length: 0 },
          length: 0,
          pipes: [],
          flowing: true,
          ended: false,
          endEmitted: false,
          reading: true,
          sync: false,
          needReadable: true,
          emittedReadable: false,
          readableListening: false,
          resumeScheduled: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          destroyed: false,
          errored: null,
          closed: false,
          closeEmitted: false,
          defaultEncoding: 'utf8',
          awaitDrainWriters: null,
          multiAwaitDrain: false,
          readingMore: false,
          decoder: null,
          encoding: null,
          [Symbol(kPaused)]: false
        },
        _events: [Object: null prototype] {
          end: [Array],
          timeout: [Function: socketOnTimeout],
          data: [Function: bound socketOnData],
          error: [Function: socketOnError],
          close: [Array],
          drain: [Function: bound socketOnDrain],
          resume: [Function: onSocketResume],
          pause: [Function: onSocketPause]
        },
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: WritableState {
          objectMode: false,
          highWaterMark: 16384,
          finalCalled: false,
          needDrain: false,
          ending: false,
          ended: false,
          finished: false,
          destroyed: false,
          decodeStrings: false,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: true,
          bufferProcessing: false,
          onwrite: [Function: bound onwrite],
          writecb: null,
          writelen: 0,
          afterWriteTickInfo: null,
          buffered: [],
          bufferedIndex: 0,
          allBuffers: true,
          allNoop: true,
          pendingcb: 0,
          prefinished: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          errored: null,
          closed: false,
          closeEmitted: false
        },
        allowHalfOpen: true,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        _server: Server {
          maxHeaderSize: undefined,
          insecureHTTPParser: undefined,
          _events: [Object: null prototype],
          _eventsCount: 2,
          _maxListeners: undefined,
          _connections: 1,
          _handle: [TCP],
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 0,
          keepAliveTimeout: 5000,
          maxHeadersCount: null,
          headersTimeout: 60000,
          requestTimeout: 0,
          _connectionKey: '6::::4200',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(kCapture)]: false,
          [Symbol(async_id_symbol)]: 7
        },
        parser: HTTPParser {
          '0': [Function: bound setRequestTimeout],
          '1': [Function: parserOnHeaders],
          '2': [Function: parserOnHeadersComplete],
          '3': [Function: parserOnBody],
          '4': [Function: parserOnMessageComplete],
          '5': [Function: bound onParserExecute],
          '6': [Function: bound onParserTimeout],
          _headers: [],
          _url: '',
          socket: [Circular *1],
          incoming: [Circular *2],
          outgoing: null,
          maxHeaderPairs: 2000,
          _consumed: true,
          onIncoming: [Function: bound parserOnIncoming],
          [Symbol(resource_symbol)]: [HTTPServerAsyncResource]
        },
        on: [Function: socketListenerWrap],
        addListener: [Function: socketListenerWrap],
        prependListener: [Function: socketListenerWrap],
        _paused: false,
        _httpMessage: ServerResponse {
          _events: [Object: null prototype],
          _eventsCount: 1,
          _maxListeners: undefined,
          outputData: [],
          outputSize: 0,
          writable: true,
          destroyed: false,
          _last: false,
          chunkedEncoding: false,
          shouldKeepAlive: true,
          _defaultKeepAlive: true,
          useChunkedEncodingByDefault: true,
          sendDate: true,
          _removedConnection: false,
          _removedContLen: false,
          _removedTE: false,
          _contentLength: null,
          _hasBody: true,
          _trailer: '',
          finished: false,
          _headerSent: false,
          socket: [Circular *1],
          _header: null,
          _keepAliveTimeout: 5000,
          _onPendingData: [Function: bound updateOutgoingData],
          _sent100: false,
          _expect_continue: false,
          req: [Circular *2],
          locals: [Object: null prototype] {},
          [Symbol(kCapture)]: false,
          [Symbol(kNeedDrain)]: false,
          [Symbol(corked)]: 0,
          [Symbol(kOutHeaders)]: [Object: null prototype]
        },
        [Symbol(async_id_symbol)]: 10,
        [Symbol(kHandle)]: TCP {
          reading: true,
          onconnection: null,
          _consumed: true,
          [Symbol(owner_symbol)]: [Circular *1]
        },
        [Symbol(kSetNoDelay)]: false,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBuffer)]: null,
        [Symbol(kBufferCb)]: null,
        [Symbol(kBufferGen)]: null,
        [Symbol(kCapture)]: false,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(RequestTimeout)]: undefined
      },
      _consuming: true,
      _dumped: false,
      next: [Function: next],
      baseUrl: '',
      originalUrl: '/upload',
      _parsedUrl: Url {
        protocol: null,
        slashes: null,
        auth: null,
        host: null,
        port: null,
        hostname: null,
        hash: null,
        search: null,
        query: null,
        pathname: '/upload',
        path: '/upload',
        href: '/upload',
        _raw: '/upload'
      },
      params: {},
      query: {},
      res: <ref *3> ServerResponse {
        _events: [Object: null prototype] { finish: [Function: bound resOnFinish] },
        _eventsCount: 1,
        _maxListeners: undefined,
        outputData: [],
        outputSize: 0,
        writable: true,
        destroyed: false,
        _last: false,
        chunkedEncoding: false,
        shouldKeepAlive: true,
        _defaultKeepAlive: true,
        useChunkedEncodingByDefault: true,
        sendDate: true,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: null,
        _hasBody: true,
        _trailer: '',
        finished: false,
        _headerSent: false,
        socket: <ref *1> Socket {
          connecting: false,
          _hadError: false,
          _parent: null,
          _host: null,
          _readableState: [ReadableState],
          _events: [Object: null prototype],
          _eventsCount: 8,
          _maxListeners: undefined,
          _writableState: [WritableState],
          allowHalfOpen: true,
          _sockname: null,
          _pendingData: null,
          _pendingEncoding: '',
          server: [Server],
          _server: [Server],
          parser: [HTTPParser],
          on: [Function: socketListenerWrap],
          addListener: [Function: socketListenerWrap],
          prependListener: [Function: socketListenerWrap],
          _paused: false,
          _httpMessage: [Circular *3],
          [Symbol(async_id_symbol)]: 10,
          [Symbol(kHandle)]: [TCP],
          [Symbol(kSetNoDelay)]: false,
          [Symbol(lastWriteQueueSize)]: 0,
          [Symbol(timeout)]: null,
          [Symbol(kBuffer)]: null,
          [Symbol(kBufferCb)]: null,
          [Symbol(kBufferGen)]: null,
          [Symbol(kCapture)]: false,
          [Symbol(kBytesRead)]: 0,
          [Symbol(kBytesWritten)]: 0,
          [Symbol(RequestTimeout)]: undefined
        },
        _header: null,
        _keepAliveTimeout: 5000,
        _onPendingData: [Function: bound updateOutgoingData],
        _sent100: false,
        _expect_continue: false,
        req: [Circular *2],
        locals: [Object: null prototype] {},
        [Symbol(kCapture)]: false,
        [Symbol(kNeedDrain)]: false,
        [Symbol(corked)]: 0,
        [Symbol(kOutHeaders)]: [Object: null prototype] { 'x-powered-by': [Array] }
      },
      route: Route {
        path: '/upload',
        stack: [ [Layer], [Layer] ],
        methods: { post: true }
      },
      body: [Object: null prototype] {
        zip: 'PK\x03\x04\x14\x00\x00\x00\x00\x00\x04z\x0BIJH\x18"�\x02\x00\x00�\x02\x00\x007\x00\x00\x00358f7f9cd50126e4_14709282650000_drills-plated-all.drillM48\r\n' +
          'M71,TZ\r\n' +
          'FMAT,2\r\n' +
          'T1C0.635\r\n' +
          'T2C1.15\r\n' +
          'T3C1.4\r\n' +
          'T4C3.0\r\n' +
          '%\r\n' +
          'T1\r\n' +
          'X10.8Y20.725\r\n' +
          'X2.3Y3.7\r\n' +
          'X40.15Y20.05\r\n' +
          'X51.7Y22.0\r\n' +
          'X25.15Y3.7\r\n' +
          'X28.85Y22.0\r\n' +
          'X48.0Y3.7\r\n' +
          'X-12.05Y20.725\r\n' +
          'X33.65Y20.725\r\n' +
          'X-7.55Y24.364645\r\n' +
          'X6.0Y22.0\r\n' +
          'X17.3Y20.05\r\n' +
          'X15.3Y24.364645\r\n' +
          'X-5.55Y20.05\r\n' +
          'X38.15Y24.364645\r\n' +
          'T2\r\n' +
          'X51.755Y1.225\r\n' +
          'X49.215Y1.225\r\n' +
          'X46.675Y1.225\r\n' +
          'X44.135Y1.225\r\n' +
          'X41.595Y1.225\r\n' +
          'X28.905Y1.225\r\n' +
          'X26.365Y1.225\r\n' +
          'X23.825Y1.225\r\n' +
          'X21.285Y1.225\r\n' +
          'X18.745Y1.225\r\n' +
          'X6.055Y1.225\r\n' +
          'X3.515Y1.225\r\n' +
          'X0.975Y1.225\r\n' +
          'X-1.565Y1.225\r\n' +
          'X-4.105Y1.225\r\n' +
          'T3\r\n' +
          'X35.375Y2.525\r\n' +
          'X35.375Y7.525\r\n' +
          'X-10.325Y2.525\r\n' +
          'X-10.325Y7.525\r\n' +
          'X12.525Y2.525\r\n' +
          'X12.525Y7.525\r\n' +
          'T4\r\n' +
          'X45.8Y29.2\r\n' +
          'X22.95Y29.2\r\n' +
          'X0.1Y29.2\r\n' +
          'T00\r\n' +
          'M30\r\n' +
          'PK\x01\x02\x14\x03\x14\x00\x00\x00\x00\x00\x04z\x0BIJH\x18"�\x02\x00\x00�\x02\x00\x007\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00��\x00\x00\x00\x00358f7f9cd50126e4_14709282650000_drills-plated-all.drillPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00e\x00\x00\x00�\x02\x00\x00\x00\x00'
      },
      __onFinished: null,
      [Symbol(kCapture)]: false,
      [Symbol(RequestTimeout)]: undefined
    }
    


  • Apparently your server needs form-data named "file".
    So at least it should be QVariant("form-data; name=\"file\"").
    Or maybe also add other params like QVariant("form-data; name=\"file\"; fieldname=\"zip\"").



  • @Bonnie Thank you for your advice! I tried that however it didn't work. The only difference is that the beginning part of the last body field changed from

    body: [Object: null prototype] {
        zip: 'PK\x03\x04\x14\x00\x00\x00\x00\x00\x04z\x0BIJH\x18"�\x02\x00\x00�\x02\x00\x007\x00\x00\x00358f7f9cd50126e4_14709282650000_drills-plated-all.drillM48\r\n' +
          'M71,TZ\r\n' +
    

    to

    body: [Object: null prototype] {
    	    file: 'PK\x03\x04\x14\x00\x00\x00\x00\x00\x04z\x0BIJH\x18"�\x02\x00\x00�\x02\x00\x007\x00\x00\x00358f7f9cd50126e4_14709282650000_drills-plated-all.drillM48\r\n' +
    

    and the file upload still fails.
    I just realized there is a major difference in the successful upload, the successful body part looks like

    body: [Object: null prototype] {},
      file: {
        fieldname: 'zip',
        originalname: '3-half-bridges-board_drill.zip',
        encoding: '7bit',
        mimetype: 'application/zip',
        destination: './tmp/',
        filename: '13289ddcca83407a7770faeda5bd62a4',
        path: 'tmp/13289ddcca83407a7770faeda5bd62a4',
        size: 851
      },
    

    I don't know why this happens. Can someone explain? Thanks!



  • @never0lie
    Oh, ok, I didn't read your code and log carefully enough, that's just my working code for some server...I may need to take it back...
    Your successful upload seems to have an empty body, but with QHttpPart, the data should always go to the body.
    Is there any way to print the raw / unparsed data?



  • @Bonnie Okay I think I got the raw data. Correct me if I am wrong.
    Successful upload:

    POST /upload HTTP/1.1
    Host: localhost:4200
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Content-Type: multipart/form-data; boundary=---------------------------4841422831862908953042778266
    Content-Length: 1093
    Origin: http://localhost:4200
    Referer: http://localhost:4200/
    Upgrade-Insecure-Requests: 1
    Connection: keep-alive
    
    -----------------------------4841422831862908953042778266
    Content-Disposition: form-data; name="zip"; filename="3-half-bridges-board_drill.zip"
    Content-Type: application/zip
    
    PK�����zIJH"ƒ��ƒ��7���358f7f9cd50126e4_14709282650000_drills-plated-all.drillM48
    M71,TZ
    FMAT,2
    T1C0.635
    T2C1.15
    T3C1.4
    T4C3.0
    %
    T1
    X10.8Y20.725
    X2.3Y3.7
    X40.15Y20.05
    X51.7Y22.0
    X25.15Y3.7
    X28.85Y22.0
    X48.0Y3.7
    X-12.05Y20.725
    X33.65Y20.725
    X-7.55Y24.364645
    X6.0Y22.0
    X17.3Y20.05
    X15.3Y24.364645
    X-5.55Y20.05
    X38.15Y24.364645
    T2
    X51.755Y1.225
    X49.215Y1.225
    X46.675Y1.225
    X44.135Y1.225
    X41.595Y1.225
    X28.905Y1.225
    X26.365Y1.225
    X23.825Y1.225
    X21.285Y1.225
    X18.745Y1.225
    X6.055Y1.225
    X3.515Y1.225
    X0.975Y1.225
    X-1.565Y1.225
    X-4.105Y1.225
    T3
    X35.375Y2.525
    X35.375Y7.525
    X-10.325Y2.525
    X-10.325Y7.525
    X12.525Y2.525
    X12.525Y7.525
    T4
    X45.8Y29.2
    X22.95Y29.2
    X0.1Y29.2
    T00
    M30
    PK�����zIJH"ƒ��ƒ��7�����������¤����358f7f9cd50126e4_14709282650000_drills-plated-all.drillPK������e���Ø����
    -----------------------------4841422831862908953042778266--
    

    from QHttpMultiPart

    POST /upload HTTP/1.1
    Host: localhost:4200
    Content-Type: multipart/form-data; boundary="boundary_.oOo._PFFay6bRVYznGcyiqa8QpglQGLAQk7Zh"
    MIME-Version: 1.0
    Content-Length: 1052
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,*
    User-Agent: Mozilla/5.0
    Connection: keep-alive
    
    --boundary_.oOo._PFFay6bRVYznGcyiqa8QpglQGLAQk7Zh
    Content-Type: application/zip
    Content-Disposition: form-data; name="file"; fieldname="zip"
    
    PK�����zIJH"ƒ��ƒ��7���358f7f9cd50126e4_14709282650000_drills-plated-all.drillM48
    M71,TZ
    FMAT,2
    T1C0.635
    T2C1.15
    T3C1.4
    T4C3.0
    %
    T1
    X10.8Y20.725
    X2.3Y3.7
    X40.15Y20.05
    X51.7Y22.0
    X25.15Y3.7
    X28.85Y22.0
    X48.0Y3.7
    X-12.05Y20.725
    X33.65Y20.725
    X-7.55Y24.364645
    X6.0Y22.0
    X17.3Y20.05
    X15.3Y24.364645
    X-5.55Y20.05
    X38.15Y24.364645
    T2
    X51.755Y1.225
    X49.215Y1.225
    X46.675Y1.225
    X44.135Y1.225
    X41.595Y1.225
    X28.905Y1.225
    X26.365Y1.225
    X23.825Y1.225
    X21.285Y1.225
    X18.745Y1.225
    X6.055Y1.225
    X3.515Y1.225
    X0.975Y1.225
    X-1.565Y1.225
    X-4.105Y1.225
    T3
    X35.375Y2.525
    X35.375Y7.525
    X-10.325Y2.525
    X-10.325Y7.525
    X12.525Y2.525
    X12.525Y7.525
    T4
    X45.8Y29.2
    X22.95Y29.2
    X0.1Y29.2
    T00
    M30
    PK�����zIJH"ƒ��ƒ��7�����������¤����358f7f9cd50126e4_14709282650000_drills-plated-all.drillPK������e���Ø����
    --boundary_.oOo._PFFay6bRVYznGcyiqa8QpglQGLAQk7Zh--
    

    I hope this info would be helpful. Thanks again!



  • @never0lie
    Looks like the only difference in the file part is the Content-Disposition header.
    As you can see, the one from your successful upload is QVariant("form-data; name=\"zip\"; filename=\"3-half-bridges-board_drill.zip\"").
    I'm not sure if this is the key part (to have a filename?) but you can start with that.



  • @Bonnie Thank you so much! That was exactly the problem! I can successfully upload the file with QHttpMultipart right now!


Log in to reply