Created
June 23, 2018 05:20
-
-
Save azzgo/76e513bd45e4bf2e4330f74bb3f857d8 to your computer and use it in GitHub Desktop.
simple upload node server without 3rd library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// some code from <https://stackoverflow.com/questions/46629086/node-js-file-upload-server-without-third-party-module> | |
var http = require('http'); | |
var fs = require('fs') | |
var buffer = require('buffer') | |
function parseForm(boundary, data){ | |
var form = {}; | |
var delimiter = Buffer.from("\r\n--" + boundary); | |
var body = extract(data, "--" + boundary + "\r\n"); | |
var CR = Buffer.from("\r\n\r\n"); | |
var i = 0; | |
var head; | |
var name; | |
var filename; | |
var value; | |
var obj; | |
if (body) { | |
while (i !== -1){ | |
[head, i] = extract(body, i, CR); | |
name = extract(head, '; name="', '"').toString(); | |
filename = extract(head, '; filename="', '"').toString(); | |
[value, i] = extract(body, i, delimiter); | |
if (name){ | |
obj = filename ? {filename, value} : {value}; | |
if (form.hasOwnProperty(name)){ // multiple | |
if (Array.isArray(form[name])){ | |
form[name].push(obj); | |
} else { | |
form[name] = [form[name], obj]; | |
} | |
} else { | |
form[name] = obj; | |
} | |
} | |
if (body[i] === 45 && body[i + 1] === 45) break; // "--" | |
if (body[i] === 13 && body[i + 1] === 10){ | |
i += 2; // "\r\n" | |
} else { | |
//error | |
} | |
} | |
} | |
return form; | |
} | |
function extract(arr, start, end){ | |
if (!arr) { | |
return | |
} | |
var useIndex = typeof start === "number", | |
i, | |
j; | |
if (useIndex){ | |
i = start; | |
if (end){ | |
j = arr.indexOf(end, i); | |
return (j === -1) ? ["", -1] : [ (i === j) ? "" : arr.slice(i, j), j + end.length]; | |
} else return arr.slice(i); | |
} else { | |
i = arr.indexOf(start); | |
if (i !== -1){ | |
i += start.length; | |
if (end){ | |
j = arr.indexOf(end, i); | |
if (j !== -1) return arr.slice(i, j); | |
} else return arr.slice(i); | |
} | |
return ""; | |
} | |
} | |
http | |
.createServer(function(req, res) { | |
if ( | |
req.url === '/upload' | |
&& | |
req.method === 'POST' | |
&& | |
req.headers['content-type'].indexOf('multipart/form-data') > -1 | |
) { | |
let boundary = req.headers['content-type'].match(/boundary=(.*)/)[1] | |
let data = new buffer.Buffer(parseInt(req.headers['content-length'], 10)) | |
let pos = 0 | |
req.on('data', chunk => { | |
data.fill(chunk, pos) | |
pos += chunk.length | |
}) | |
req.on('end', () => { | |
var parseData = parseForm(boundary, data) | |
var file = parseData.file | |
fs.createWriteStream(file.filename).end(file.value) | |
res.end('ok'); | |
}); | |
} else { | |
// show a file upload form | |
res.writeHead(200, { 'content-type': 'text/html' }); | |
res.end( | |
'<form action="/upload" enctype="multipart/form-data" method="post">' + | |
'<input type="file" name="file" multiple="multiple"><br>' + | |
'<input type="submit" value="Upload">' + | |
'</form>' | |
); | |
} | |
}) | |
.listen(8080); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment