Firebase Functions Multipart/formdata Error - html

My webpage provides functionallity to convert pdf to image.
For Webpage i am using Firebase Hosting and for functions obvs Functions.
But after file upload function logs error in firebase dashboard Boundary not found
Below is the code i used to upload file in html:
function uploadFile() {
var file = document.getElementById("file_input").files[0];
var pass = document.getElementById("pass").value;
console.log(file + pass);
var formdata = new FormData();
formdata.append("file", file);
formdata.append("password", pass);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "/upload");
ajax.setRequestHeader("Content-Type", "multipart/form-data");
ajax.send(formdata);
}
and this is the code of functions:
var functions = require('firebase-functions');
var process;
var Busboy;
var path = require('path');
var os = require('os');
var fs = require('fs');
exports.upload = functions.https.onRequest((req, res) => {
const busboy = new Busboy({ headers: req.headers });
const fields = {};
const tmpdir = os.tmpdir();
const uploads = {};
const fileWrites = [];
var pass = '';
busboy.on('file', (fieldname, file, filename) => {
console.log(`Processed file ${filename}`);
const filepath = path.join(tmpdir, filename);
uploads[fieldname] = filepath;
const writeStream = fs.createWriteStream(filepath);
file.pipe(writeStream);
const promise = new Promise((resolve, reject) => {
file.on('end', () => {
writeStream.end();
});
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
fileWrites.push(promise);
});
busboy.on('field', function (fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
pass = val;
});
busboy.on('finish', function () {
console.log('Done parsing form!');
console.log(pass);
console.log(uploads);
process.processCard(uploads['file'], pass, 2).then((s) => {
res.end(`
<!DOCTYPE html>
<html>
<body>
ImageConverted!!
<img src="data:image/jpeg;base64,${s}" width="90%"></img>
</body>
</html>
`);
}).catch((err) => { res.end('Error: ' + err) });
});
busboy.end(req.body);
});
What am i doing wrong ?

For multipart body it is recommended to use req.rawBody instead of req.body
https://stackoverflow.com/a/48289899/6003934

Related

How can i make the HTML file open in Chrome while the calling browser is Explorer

I have this HTML (attached).
It is called by a web app that still works on I.E (for at least one or two months) due to some problems we have with the vendor.
The web app calls this HTML and it is opened in I.E also.
I need this HTML to be opened in Chrome.
Is there a way i can do this by adding something to the HTML itself?
<html>
<head>
<script>
async function setSRC(){
try{
var xhr;
const params = new Proxy(new URLSearchParams(window.location.search),
{
get: (searchParams, prop) => searchParams.get(prop),
});
var docId = params.docId;
var url = "``http://wsp-exttest.lcardtest.corp:4440/rest.oms/MaxRestService/getPDF?docId=``" + docId;
let response = await new Promise(resolve => {
xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onload = function(e) {
resolve(xhr.response);
};
xhr.onerror = function () {
resolve(undefined);
console.error("** An error occurred during the XMLHttpRequest");
};
xhr.send();
})
//
var j = JSON.parse(xhr.responseText);
var pdfData = j[0].content;
var letterFrame = document.getElementById("letterFrame");
letterFrame.src = "data:application/pdf;base64," + pdfData;
/*letterFrame.onreadystatechange = () => {
if (letterFrame.readyState === 'complete') {
alert(letterFrame.readyState);
letterFrame.src = "data:application/pdf;base64," + pdfData;
}
};*/
}
catch(e)
{
if(confirm("Load faile: " + e.message + "click ok to retry"))
setSRC();
}
}
</script>
</head>
<body onload="setSRC()">
<iframe id="letterFrame" width="1200px" height="800px" onload=""></iframe>
Reload
</body>
</html>
Reload

Add Revit Levels and 2D Minimap to your 3D for local viewer

In our project, we use a local viewer and we do not receive data from a request, but we have it locally.
And getting data from our local files it is impossible to insert it into the panel.
And the call doc.downloadAecModelData() returns null.
See more https://forge.autodesk.com/blog/add-revit-levels-and-2d-minimap-your-3d
Autodesk.Viewing.Initializer(options, async () => {
const config3d = {
useConsolidation: true,
useADP: false,
extensions: [
"Autodesk.Viewing.MarkupsCore",
"MarkupExtension",
"Autodesk.AEC.LevelsExtension",
"Autodesk.AEC.Minimap3DExtension"
]
};
const init_div = document.getElementById("init_div");
const svf_path = "/storage/" + decodeURIComponent(props.search.split("&&")[1]);
const p = "/storage/" + props.search.split("&&")[1];
const viewer = new Autodesk.Viewing.GuiViewer3D(init_div, config3d);
Autodesk.Viewing.endpoint.getItemApi = (endpoint, derivativeUrn, api) => {
return (
"/storage/5bf49c73e2ac26b2756b642ae1b29037/aa1bb3d5baaa229e0c15e674adb7aceec1a0fb061e9c0288d9979f801fb6460d.svf/Resource" +
decodeURIComponent(p.split("Resource")[1])
);
};
const paths = svf_path.split("/");
const [dest, svf_dir] = [paths[2], paths[3]];
const url = http://localhost:3000/api/viewer/dest/${dest}/svf/${svf_dir}/manifest;
const response = await fetch(url);
const manifest = await response.json();
const aec_url = /api/viewer/dest/${dest}/svf/${svf_dir}/aec;
const response_aec = await fetch(aec_url);
const aec = JSON.parse(await response_aec.json());
// console.log(aec);
const viewerDocument = new Autodesk.Viewing.Document(manifest);
const a = await viewerDocument.downloadAecModelData();
console.log(a);
console.log(manifest);
const viewable = viewerDocument.getRoot().getDefaultGeometry();
viewable.data.aec_odel_data = aec;
// console.log(viewable);
await Autodesk.Viewing.Initializer(options, () => {
// const aec = viewable.parent.children[1].data; //.urn//.split("Resource")[1];
// for resize and use viewer outer useEffect
props.set_loc_viewer(viewer);
viewer.start();
viewer.loadDocumentNode(viewerDocument, viewable, options);
});
As i know you can only use doc.downloadAecModelData() after document loaded, like this:
onDocumentLoadSuccess(doc: Autodesk.Viewing.Document) {doc.downloadAecModelData(); }

Hello how to upload an image using angularjs+mysql+node.js

How to upload the image in angularjs and mysql and node.js?
<html>
<head>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app = "myApp">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
</script>
</body>
</html>
AngularJs is a client side language. so it is not able to direct save data to MySql.
If any data is store in a database or in a server you must used any server side language.
You are create a web service that can tack response from client side (AngularJS) and send proper response.
File Upload in Mysql using NodeJs
fs.open(temp_path, 'r', function (status, fd) {
if (status) {
console.log(status.message);
return;
}
var buffer = new Buffer(getFilesizeInBytes(temp_path));
fs.read(fd, buffer, 0, 100, 0, function (err, num) {
var query = "INSERT INTO `files` SET ?",
values = {
file_type: 'img',
file_size: buffer.length,
file: buffer
};
mySQLconnection.query(query, values, function (er, da) {
if (er)throw er;
});
});
});
function getFilesizeInBytes(filename) {
var stats = fs.statSync(filename)
var fileSizeInBytes = stats["size"]
return fileSizeInBytes
}

gulp-dust-html watch task doesn't include updated templates

It seems that example-template.dust somehow gets cached. The first time running the gulp default task it correctly takes the current version of example-template.dust and renders it correctly in index.html.
But later changes to example-template.dust aren't included in the rendered index.html even though the watch task correctly fires and executes the dust task.
I'm thinking it has to do with some configuration errors.
Here is the gulp tasks and templates. Everything else works.
example-template.dust
Hello, from a template. Rendered with <b>{type}</b>
index.html
<!DOCTYPE html>
<html>
<head>
<title>{name}</title>
<link rel="stylesheet" href="main.css"/>
</head>
<body>
<h1>version \{version}</h1>
<p>
{>example-template type="gulp"/}<br/>
There are special escape tags that you can use to escape a raw { or } in dust.<br/>
{~lb}hello{~rb}
</p>
<script src="main.js"></script>
</body>
</html>
gulp-dust-html task
var gulp = require('gulp');
var dust = require('dustjs-linkedin');
var browserSync = require('browser-sync');
var error = require('./errorHandling.js');
var dusthtml = require('gulp-dust-html');
var config = require('../../config.js');
gulp.task('dust', function () {
return gulp.src(config.build.src+'/**/*.html')
.pipe(dusthtml({
basePath: config.build.src+'/',
data: config.build.data
}))
.on('error', error)
.pipe(gulp.dest(config.build.dev+'/'))
.pipe(browserSync.reload({stream:true}));
});
gulp.task('watch-dust', ['dust'], browserSync.reload);
watch task
var gulp = require('gulp');
var watch = require('gulp-watch');
var reload = require('browser-sync').reload;
var config = require('../../config.js');
gulp.task('watch', function() {
gulp.watch(config.build.src+"/**/*.scss", ['sass', reload]);
gulp.watch(config.build.images, ['images', reload]);
gulp.watch([config.build.src+"/**/*.dust"], ['watch-dust', reload]);
gulp.watch([config.build.src+"/**/*.html"], ['watch-dust', reload]);
});
default gulp task
gulp.task('default', ['browserSync','images', 'iconFont', 'sass', 'js', 'dust', 'watch']);
I'm open for alternative suggestions as well.
Atm I'm thinking it could be an idea to use https://www.npmjs.com/package/gulp-shell and link it to the watch task.
ps: I don't have enough reputation to create a gulp-dust-html tag
As #Interrobang said, dust.config.cache = false solved it.
Here is the updated gulp-dust-html module (not on npm)
'use strict';
var gutil = require('gulp-util');
var path = require('path');
var fs = require('fs');
var through = require('through2');
var dust = require('dustjs-linkedin');
module.exports = function (options) {
if (!options)
options = {}
var basePath = options.basePath || '.';
var data = options.data || {};
var defaultExt = options.defaultExt || '.dust';
var whitespace = options.whitespace || false;
dust.config.cache = options.cache || false; //default cache disabling of templates.
dust.onLoad = function(filePath, callback) {
if(!path.extname(filePath).length)
filePath += defaultExt;
if(filePath.charAt(0) !== "/")
filePath = basePath + "/" + filePath;
fs.readFile(filePath, "utf8", function(err, html) {
if(err) {
console.error("Template " + err.path + " does not exist");
return callback(err);
}
try {
callback(null, html);
} catch(err) {
console.error("Error parsing file", err);
}
});
};
if (whitespace)
dust.optimizers.format = function (ctx, node) { return node; };
return through.obj(function (file, enc, cb) {
if (file.isNull()) {
this.push(file);
return cb();
}
if (file.isStream()) {
this.emit('error', new gutil.PluginError('gulp-dust', 'Streaming not supported'));
return cb();
}
try {
var contextData = typeof data === 'function' ? data(file) : data;
var finalName = typeof name === 'function' && name(file) || file.relative;
var tmpl = dust.compileFn(file.contents.toString(), finalName);
var that = this;
tmpl(contextData, function(err, out){
if (err){
that.emit('error', new gutil.PluginError('gulp-dust', err));
return;
}
file.contents = new Buffer(out);
file.path = gutil.replaceExtension(file.path, '.html');
that.push(file);
cb();
})
} catch (err) {
this.emit('error', new gutil.PluginError('gulp-dust', err));
}
});
};

decodeAudioData failing with null errors on continuous stream

In my following code ffmpeg is transcoding the input stream and is successfully sending the chunks to the client. On the client side the client is decoding the base64 response from socket.io and is converting the response to an array buffer. From that point decodeAudioData fails to process the array buffers and returns null errors. Does anyone know why decodeAudioData isn't working?
./webaudio_svr.js:
var express = require('/usr/local/lib/node_modules/express');
var http = require('http');
var spawn = require('child_process').spawn;
var util = require('util');
var fs = require('fs');
var app = express();
var webServer = http.createServer(app);
var audServer = http.createServer(app);
var io = require('/usr/local/lib/node_modules/socket.io').listen(webServer, {log: false, });
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.send(
"<script src='/socket.io/socket.io.js'></script>\n"+
"<script>var socket=io.connect('http://127.0.0.1:3000');</script>\n"+
"<script src='/webaudio_cli.js'></script>"
);
});
webServer.listen(3000);
var inputStream = spawn('/usr/bin/wget', ['-O','-','http://nprdmp.ic.llnwd.net/stream/nprdmp_live01_mp3']);
var ffmpeg = spawn('ffmpeg', [
'-i', 'pipe:0', // Input on stdin
'-ar', '44100', // Sampling rate
'-ac', 2, // Stereo
'-f', 'mp3',
'pipe:1' // Output on stdout
]);
io.sockets.on('connection', function(webSocket) {
var disconnect = '0';
if (disconnect == '0') {
inputStream.stdout.pipe(ffmpeg.stdin);
ffmpeg.stdout.on('data', function(data) {
var data64 = data.toString('base64');
webSocket.emit('stream',data64);
});
}
webSocket.on('disconnect', function() {
disconnect=1;
});
});
./public/webaudio_cli.js:
function str2ab(str) {
var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i=0, strLen=str.length; i<strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var source = context.createBufferSource();
socket.on('stream', function(data) {
var data=str2ab(atob(data));
context.decodeAudioData(data, function(buffer) {
source.connect(context.destination);
source.buffer = buffer;
source.start(0);
}, function(err) {
console.log("err(decodeAudioData): "+err);
});
});
If you read the notes section of the original post you'll see that I ended up getting this working with binaryjs but with the help of Kevin I was able to get this to work with socket.io. Note there this is still a HUGE issue with choppy playback. If someone could lend some assistance to cleaning the audio up please do. This solution is really pointless unless the audio works as expected so I need to figure that out.
The issue has to do with how the browser encodes/decodes your base64 string. Until this is changed you must supply your own functions from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding.
webaudio_svr.js:
var express = require('/usr/local/lib/node_modules/express');
var http = require('http');
var spawn = require('child_process').spawn;
var util = require('util');
var fs = require('fs');
var app = express();
var webServer = http.createServer(app);
var io = require('/usr/local/lib/node_modules/socket.io').listen(webServer, {log: false, });
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.send(
"<script src='/socket.io/socket.io.js'></script>\n"+
"<script>var socket=io.connect('http://127.0.0.1:3000');</script>\n"+
"<script src='/base64.js'></script>\n"+
"<script src='/webaudio_cli.js'></script>"
);
});
webServer.listen(3000);
var inputStream = spawn('/usr/bin/wget', ['-O','-','http://nprdmp.ic.llnwd.net/stream/nprdmp_live01_mp3']);
var ffmpeg = spawn('ffmpeg', [
'-i', 'pipe:0', // Input on stdin
'-ar', '44100', // Sampling rate
'-ac', 2, // Stereo
'-f', 'mp3',
'pipe:1' // Output on stdout
]);
io.sockets.on('connection', function(webSocket) {
var disconnect = '0';
if (disconnect == '0') {
inputStream.stdout.pipe(ffmpeg.stdin);
ffmpeg.stdout.on('data', function(data) {
var data64 = data.toString('base64');
webSocket.emit('stream',data64);
});
}
webSocket.on('disconnect', function() {
disconnect=1;
});
});
public/webaudio_cli.js:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var startTime = context.currentTime;
// buffer to arraybuffer
function toArrayBuffer(buffer) {
var ab = new ArrayBuffer(buffer.length);
var view = new Uint8Array(ab);
for (var i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return ab;
}
socket.on('stream', function(data) {
var data=toArrayBuffer(base64DecToArr(data));
context.decodeAudioData(data, function(buffer) {
playBuffer(buffer);
}, function(err) {
console.log("decodeAudioData err: "+err);
});
});
function playBuffer(buf) {
var source = context.createBufferSource();
source.buffer = buf;
source.connect(context.destination);
source.start(startTime);
startTime = startTime+source.buffer.duration;
}
public/base64.js:
copy and paste functions from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding#Solution_.232_.E2.80.93_rewriting_atob()_and_btoa()_using_TypedArrays_and_UTF-8