0

I'm trying to replicate the functionality of bashupload.com but using node. I want the simplicity of just doing curl host -T file but I ran into some problems because I can't seem to understand how to read the PUT file. Curl uses a PUT request when you use the -T option, so it has to be PUT.

I tried using packages like multiparty:

receiveAndUploadFile: function (req, res) {
        var multiparty = require('multiparty');
        var form = new multiparty.Form();
        // var fs = require('fs');
        
        form.parse(req, function(err, fields, files) {  
            console.log('The files', files)
            console.log('The fields', fields)
        })
      
        res.send("Okay, bye.")
    }

But this prints undefined values for files and fields.

I also tried using express-fileupload middleware

app.use(fileUpload({}));

but still, if I try to print req.files then I will get undefined.

Is there any specific way to read the file? Thanks a lot!


This is my main file, index.js::

const express = require("express");
const path = require("path");
const app = express();
const port = 8080;
const tools = require("./tools");
const fileUpload = require("express-fileupload");

app.use(fileUpload());
app.use(express.static(__dirname + "/assets"));

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname + "/index.html"));
});

app.get("/f", (req, res) => {
  res.send("This route is only available as a POST route.");
});
app.put("/f", tools.receiveAndUploadFile);

app.listen(port, () => {
  console.log(`Server started listening on port: ${port}`);
});


And the tools.js file:

const fs = require("fs");
const path = require("path");

module.exports = {
  receiveAndUploadFile: function (req, res) {
    console.log("Files: ", req.files);
    res.send("Okay bye");
  },
};

This is printing "Files: undefined" to the console.

Camilo Urán
  • 387
  • 4
  • 12
  • Can you post your whole server code? A minimal [reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) is handy. – Kelvin Schoofs Jul 24 '21 at 13:39
  • According to the [`express-fileupload` README](https://www.npmjs.com/package/express-fileupload), it's supposed to with with `` tags in HTML forms. I don't know how `curl -T` formats the body (or `Content-Type` header), but perhaps they're just incompatible. I suggest uploading a simple text while of a few bytes and checking the raw HTTP request. – Kelvin Schoofs Jul 24 '21 at 14:16
  • If it helps, here is the PHP code for bashupload.com: https://github.com/IO-Technologies/bashupload/blob/main/actions/upload.php they apparently read raw data from php://input. Is there an equivalent version of this in Node? – Camilo Urán Jul 24 '21 at 14:35
  • I found [this question](https://stackoverflow.com/questions/9920208/expressjs-raw-body) that might help you with that. I don't know the Express API well enough to give you a direct answer myself. – Kelvin Schoofs Jul 24 '21 at 14:40
  • Thank you. I have decided that Node.JS is too cumbersome for this task, and I will just use the PHP script from bashupload.com – Camilo Urán Jul 24 '21 at 15:01

1 Answers1

0

A PUT and a POST are effectively the same thing. To upload arbitrary data, just read the data stream and write it to a file. Node provides a .pipe method on streams to easily pipe data from one stream into another, for example a file stream here:

const fs = require('fs')
const express = require('express')

const app = express()
const PORT = 8080

app.get('/*', (req, res) => res.status(401).send(req.url + ': This route is only available as a POST route'))

app.put('/*', function (req, res, next) {
  console.log('Now uploading', req.url, ': ', req.get('content-length'), 'bytes')
  req.pipe(fs.createWriteStream(__dirname + req.url))
  req.on('end', function () { // Done reading!
    res.sendStatus(200)
    console.log('Uploaded!')
    next()
  })
})
app.listen(8080, () => console.log('Started on :8080'))

If you do a PUT to /file.mp4, it will upload all the data over to the script dir (__dirname) + the URL file path.

via curl, curl http://localhost:8080/ -T hello.txt

Extreme
  • 315
  • 4
  • 7