5

How do I upload a file to a remote server with the node http module (and no 3rd party libs)?

I tried the following but it's not working (I get no data on the server):

function writeBinaryPostData(req, filepath) {
    var fs = require('fs');

    var boundaryKey = Math.random().toString(16); // random string
    var boundaryStart = `--${boundaryKey}\r\n`,
        boundaryEnd = `\r\n--${boundaryKey}--`,
        contentDispositionHeader = 'Content-Disposition: form-data; name="file" filename="file.txt"\r\n',
        contentTypeHeader = 'Content-Type: application/octet-stream\r\n',
        transferEncodingHeader = 'Content-Transfer-Encoding: binary\r\n';

    var contentLength = Buffer.byteLength(
        boundaryStart +
        boundaryEnd +
        contentDispositionHeader +
        contentTypeHeader +
        transferEncodingHeader
    ) + fs.statSync(filepath).size;

    var contentLengthHeader = `Content-Length: ${contentLength}\r\n`;

    req.setHeader('Content-Length', contentLength);
    req.setHeader('Content-Type',  'multipart/form-data; boundary=' + boundaryKey);

    req.write(
        boundaryStart +
        contentTypeHeader +
        contentDispositionHeader +
        transferEncodingHeader
    );

    fs.createReadStream(filepath, { bufferSize: 4 * 1024 })
        .on('data', (data) => {
            req.write(data);
        })
        .on('end', () => {
            req.write(boundaryEnd);
            req.end();
        });
}

1 Answer 1

13

I got it working with the following code:

function writeBinaryPostData(req, filepath) {
    var fs = require('fs'),
        data = fs.readFileSync(filepath);

    var crlf = "\r\n",
        boundaryKey = Math.random().toString(16),
        boundary = `--${boundaryKey}`,
        delimeter = `${crlf}--${boundary}`,
        headers = [
          'Content-Disposition: form-data; name="file"; filename="test.txt"' + crlf
        ],
        closeDelimeter = `${delimeter}--`,
        multipartBody;


    multipartBody = Buffer.concat([
        new Buffer(delimeter + crlf + headers.join('') + crlf),
        data,
        new Buffer(closeDelimeter)]
    );

    req.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
    req.setHeader('Content-Length', multipartBody.length);

    req.write(multipartBody);
    req.end();
}

based on code I found here

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, after searching for hours and trying 5 different http libraries, this finally worked!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.