unzip error [Error: invalid signature: 0xff000001] - javascript

Im using the following library for node unzip
https://github.com/EvanOxfeld/node-unzip
The code which I use is
var extractor = unzip.Extract({
path: 'C://TestFolder//TestZip'
}).on('close', function () {
console.log("Success to unzip");
}).on('error', function (err) {
console.log("error to unzip", err);
});
req.pipe(extractor);
The problem that In some zip file Im getting the error (in others its works fine)
[Error: invalid signature: 0x8080014]
[Error: invalid signature: 0x83870008]
....
This error doesnt give a lot info...
searching the web I found this
https://github.com/EvanOxfeld/node-unzip/issues/41
And install and require the unzip2 package instead of unzip ,
the issue now that Im getting the following error
unzip Error: invalid signature: 0xff000001
I use the same code for unzip and unzip2 (which I provided in the post above),do I need to use it different? any hints how to solve it?
UPDATE
I send the zip file from postman like following

You can temporary save the ZIP file on your disk, and then extract it using adm-zip.
Here is a sample code:
Client Side:
<form action="/upload" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
Server Side
Using multer to save the uploaded file, and adm-zip to extract it.
You need to install both:
npm install --save multer
npm install --save adm-zip
After installing here an example of using them together:
var multer=require('multer') // a module for saving file from form.
var AdmZip = require('adm-zip'); // a module for extracting files
var express=require('express') // module for receving HTTP traffic
var app=express()
var upload = multer({ dest: 'uploads/' })
app.post('/upload',upload.single('fileToUpload'),function(req,res){
console.log('The file uploaded to:' + req.file.path)
var zip = new AdmZip(req.file.path);
zip.extractAllTo( "/detination_folder/");
})
Information about the modules I used:
https://github.com/expressjs/multer , https://github.com/cthackers/adm-zip

Node-unzip2 patches this problem.
example :
var readStream = fs.createReadStream('path/to/archive.zip');
var writeStream = fstream.Writer('output/path');
readStream
.pipe(unzip.Parse())
.pipe(writeStream)

Try your unzip solution, but for receiving the binary data, attach this middleware and then get your file from req.rawBody:
app.use(function(req, res, next) {
var data = new Buffer('');
req.on('data', function(chunk) {
data = Buffer.concat([data, chunk]);
});
req.on('end', function() {
req.rawBody = data;
next();
});
});

As #Amina said.
You can temporary save the ZIP file on your disk, and then extract it
using whatever unzipper package like unzip,adm-zip,unzip2,unzippy or whatever you like it.
For some information, My App structure like this below :
//App path --> C:\xampp\htdocs\service
service\
|
-- tmp\
|
-- app.js
|
-- index.html
You're using unzip2 right ?
Here's my code:
Server Side:
I'm using unzip2 to extract the zipFile, you can test it using postman too. Don't forget using enctype="multipart/form-data" when you post it. :D
var express = require("express");
var fs = require("fs");
var unzip = require("unzip2");
var app = express();
var multer = require("multer");
var multer_dest = multer({dest: "./tmp"}).single('zipFile');
app.post("/upload_zip",multer_dest,function(req,res){
console.log(req.file);
fs.createReadStream(req.file.path).pipe(unzip.Extract({path: 'C:\\TestFolder\\TestZip'}));
result = {
file:req.file,
message:"File has been extracted"
};
fs.unlink(req.file.path, function (e) {
if (e) throw e;
console.log('successfully deleted '+req.file.path);
});
res.end(JSON.stringify(result));
});
var server = app.listen(8081,function(){
var host = server.address().address;
var port = server.address().port;
console.log("Example App Listening at http://%s:%s",host,port);
})
Output :

Related

Express-busboy npm create folder in public directory ExpressJs

In my controller, when I try to readFile send from browser by AJAX, suddenly 1 directory created into my public folder with something like
'3d6c3049-839b-40ce-9aa3-b76f08bf140b' -> file -> myfile
exports.assetAdd = function(req, res) {
var d = JSON.parse(req.body.data);
var f = req.files.file;
return ;
//here i can see my unwanted created directory
// Create S3 service object
var s3 = new AWS.S3({
apiVersion: '2017-03-01'
});
// console.log("file",f)
fs.readFile(f.file, function(err, data) {
return res.json(data);
How to remove this?
This is issue with the package, Already opened issue
https://github.com/yahoo/express-busboy/issues/16

How to pass parameters between node.js and HTML?

I am a new user of node.js and mongodb and still learning. Please excuse if the question seems very simple. My node.js MongoDB query script (hello.js) is-
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/flood';
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server.");
var collec_name="99"
var field_name ="data1"
var value=311
db.collection(collec_name).find({data0:value}, {[field_name]:1, _id:0}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
});
The query runs fine with command- node hello.js and got the expected value result (for instance, output value of result is 0.000115). Note that var collec_name="99", var field_name ="data1" and var value=311 contain fixed values.
My HTML file (index.html) is-
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var c_n = "99";
var f = "data1";
var v = 311;
document.getElementById("demo").innerHTML = 0.000115;
</script>
</body>
</html>
Now, I want to pass the values of variable c_n, v and f from index.html to hello.js by replacing three statements of hello.js as-
var collec_name=c_n
var field_name = f
var value = v
Then, I want to pass value of result from hello.js to the index.html by replacing one statement of index.html as-
document.getElementById("demo").innerHTML = result;
So, how can I achieve these parameter passing so that if I run the index.html page, I can display the value of result on the web? Any solution script based on my scripts will be highly appreciated.
To send data between your back-end and your client you have to use AJAX, socket.io or WebSockets.
If you only have to update the back-end if the clients wants to you should use AJAX. If your client has to be notified by the back-end (Server), you should use socket.io or WebSockets for that.
Because you are using NodeJs, i would recommend you to use socket.io.
Just have a look at it:
https://socket.io/
Here a example for your code:
First install the package:
npm install -S socket.io
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
// add socket io
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
// connect to port
app.listen(3030);
var url = 'mongodb://localhost:27017/flood';
// setup server
io.on('connection', function (socket) {
// add event
socket.on('data', function (data) {
// execute after event was emitted
MongoClient.connect(url, function (err, db) {
assert.equal(null, err);
console.log("Connected correctly to server.");
var collec_name = data.collec;
var field_name = data.field;
var value = data.value
db.collection(collec_name).find({ data0: value }, { [field_name]: 1, _id: 0 }).toArray(function (err, result) {
if (err) throw err;
// TODO add emmit
console.log(result);
db.close();
});
});
});
});
HTML:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script src="path/to/socket.io"></script>
<script>
var socket = io('http://localhost');
// send message
socket.emit('data', {
collec: "99",
field: "datal",
value: 311
});
// TODO add listener
document.getElementById("demo").innerHTML = 0.000115;
</script>
</body>
</html>
Finally, I was able to solve the problem. As I didn't find any perfect solution on net, I thought it will be helpful for other users (who are facing similar problem) if I post a general solution to a similar problem here. Please excuse if this is not the right place to post the solution.
My Solution: This is not the exact solution of my above example but I think it is better to provide a general solution to a similar problem so that anyone can always modify/update this solution according to his/her example/need as basic approach will be always same. At first, you need to have http, express and body-parser and you can do by following the commands:
npm install http
npm install express
npm install body-parser --save
A general problem: Suppose, I have two numbers (for instance a = 20 and b = 24 in the client HTML page and I want to sum up the numbers from the server side and get the summation result (sum = 44) back in the client side to display in the HTML page. Then use the following nodejs and ejs scripts-
index.ejs:
<html>
<head>
<title>Example solution</title>
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script type="text/javascript">
$(function(){
$('#loadRequest').click(function(e) {
e.preventDefault();
console.log('Load_button clicked');
var data = {};
data.a = 20; //input
data.b = 24; //input
$.ajax({
type: 'POST',
data: JSON.stringify(data), //input data to be sent to the server
contentType: 'application/json',
url: 'http://localhost:80/endpoint',
success: function(res) {
console.log('success');
console.log(res);
$("#demo").html(res); //summation displayed in the HTML page
}
});
});
});
</script>
</head>
<body>
<p id ="demo"></p>
<button id="loadRequest">Load</button>
</body>
</html>
server.js:
var http = require('http');
var express = require('express');
var app = express();
app.set('view engine', 'ejs'); //tell Express we're using EJS
app.set('views', __dirname + '/views'); //set path to *.ejs files
app.use('/public', express.static(__dirname + '/public'));
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.get('/', function(req, res) {
//render index.ejs file
res.render('index');
});
app.post('/endpoint', function(req, res){
var x = req.body.a; //received input 1 from client side
var y = req.body.b; //received input 2 from client side
console.log(x);
console.log(y);
var sum =x+y;
console.log(sum);
res.send(String(sum)); //sending summation to the client
});
http.createServer(app).listen(80);
It worked perfectly. Please let me know if you have any comment/feedback.
You can either implement an API yourself using AJAX, WebSockets or socket.io - or you can go ahead and take a look into Express framework.
Setting up a Node.js server using Express will not only provide you access to a rich API interface, it would also make your task much easier.
Using it, you can set up a simple route like this:
app.post('/compute', function(req, res){
// compute 'result'
res.send(result);
});

How to delete file after upload using node?

I am using multiparty to upload some file on the server, I have notice that when using form.parse a file is being added in temp in SO file system.
I need to remove that file after form close but I cannot get information of file path.
Any idea how to solve this problem?
function onUpload(req, res) {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
onSimpleUpload(fields, files[fileInputName][0], res);
});
// Close emitted after form parsed
form.on('close', function() {
// cannot get file here to be deleted
});
}
To be specific:
var fs = require('fs');
var filePath = files[fileInputName][0].path;
fs.unlinkSync(filePath);
or async:
var fs = require('fs');
var filePath = files[fileInputName][0].path;
fs.unlink(filePath, function(err){
if(err) // do something with error
else // delete successful
});
You can get the path of file saved on local filesystem, by files[fileInputName][0].path

Error: ENOENT, no such file or directory in meteor

Description of the problem:
Trying to import JSON file when server starts up.
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
var fs = Npm.require('fs');
Videos = fs.readFileSync("public/toc_vd_en.json", "utf8");
});
}
Getting a Error: ENOENT, no such file or directory 'public/toc_vd_en.json'
File structure:
Question:
I believe I'm giving the correct relative path. What is causing this error?
mate, try this:
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
var base = process.env.PWD;
var fs = Npm.require('fs');
Videos = fs.readFileSync(base + "/public/toc_vd_en.json", "utf8");
});
}
Videos = fs.readFileSync("public/toc_vd_en.json", "utf8");
change to
Videos = fs.readFileSync("../public/toc_vd_en.json", "utf8");

Formidable multi-file upload - ENOENT, no such file or directory

I know this question has been asked but my mind has been blown by my inability to get this working. I am trying to upload multiple images to my server with the following code:
var formidable = require('formidable');
var fs = require('fs');
...
router.post('/add_images/:showcase_id', function(req, res){
if(!admin(req, res)) return;
var form = new formidable.IncomingForm(),
files = [];
form.uploadDir = global.__project_dirname+"/tmp";
form.on('file', function(field, file) {
console.log(file);
file.image_id = global.s4()+global.s4();
file.endPath = "/img/"+file.image_id+"."+file.type.replace("image/","");
files.push({field:field, file:file});
});
form.on('end', function() {
console.log('done');
console.log(files);
db.get("SOME SQL", function(err, image_number){
if(err){
console.log(err);
}
var db_index = 0;
if(image_number) db_index = image_number.image_order;
files.forEach(function(file, index){
try{
//this line opens the image in my computer (testing)
require("sys").exec("display " + file.file.path);
console.log(file.file.path);
fs.renameSync(file.file.path, file.file.endPath);
}catch (e){
console.log(e);
}
db.run( "SOME MORE SQL"')", function(err){
if(index == files.length)
res.redirect("/admin/gallery"+req.params.showcase_id);
});
});
});
});
form.parse(req);
});
The line that opens the image via system calls works just fine, however I continue to get:
Error: ENOENT, no such file or directory '/home/[username]/[project name]/tmp/285ef5276581cb3b8ea950a043c6ed51'
by the rename statement.
the value of file.file.path is:
/home/[username]/[project name]/tmp/285ef5276581cb3b8ea950a043c6ed51
I am so confused and have tried everything. What am I doing wrong?
Probably you get this error because the target path does not exist or you don't have write permissions.
The error you get is misleading due to a bug in nodejs, see:
https://github.com/joyent/node/issues/5287
https://github.com/joyent/node/issues/685
Consider adding:
console.log(file.file.endPath);
before the fs.renameSync call and check if the target path exist and is writable by your application
You stated form. Therefore note that Formidable doesn't work out of the box with just NodeJS. Unless you were to use something like the prompt module for input. If you are using HTML, you'll need something like Angular, React or Browserify to be able to give it access to your interface.

Categories

Resources