nodejs pipe https response to request.post and write file - node.js

I am Making http proxy program that check http url and If It is download link(content-type:octet-stream), I would get response and relay that response to other computer by using request.post and other computer download file with response that are given by http proxy.
Let's suppose that web proxy computer is A. And It is part of code of A. 192.168.5.253
if(contentType && (contentType== "application/octet-stream" || contentType == "application/gzip")){
console.log("remoteRes##app",remoteRes);
let filepath = req.url.split('/');
let FileName = getFilename(remoteRes, filepath);
let writeStream = fs.createWriteStream(FileName);
/*remoteRes is octect-stream response.
I can get file buffer If I use remoteRes.on(data, chunk => {...})*/
remoteRes.pipe(writeStream); //It works but I want to send file buffer to B without writing file.
.........
I can download file in A. but I want to send this response to pc B(192.168.5.32:10001) server.
So I want to streaming like this:
remoteRes.pipe(request.post('http://192.168.5.32:10001/upload));
And this is part of Server B(192.168.5.32) code
router.post('/upload', (req, res, next) => {
let wstream = fs.createWriteStream('ffff.txt');
req.pipe(wstream); //It dosen't work, but I want to do like this.
})
I want to get filebuffer in router.post('/upload'). It dosen't matter If It is post or put.
I saw that when I use remoteRes.pipe(request.post('http://192.168.5.32:10001/upload));
,I saw that request from ServerA get to ServerB. But I couldn't get file buffer in ServerB.
In short, I want to pipe response to request.post.

You need to store the incoming buffers using your own middleware, so it will be available in the routers request handler
Here you have a working example (you can save it and test it as a single file) :
//[SERVER B]
const express = require('express'); const app = express()
//:Middleware for the incoming stream
app.use(function(req, res, next) {
console.log("[request middleware] (buffer storing)")
req.rawBody = ''
req.on('data', function(chunk) {
req.rawBody += chunk
console.log(chunk) // here you got the incoming buffers
})
req.on('end', function(){next()})
});
//:Final stream handling inside the request
app.post('/*', function (req, res) {
/* here you got the complete stream */
console.log("[request.rawBody]\n",req.rawBody)
});
app.listen(3000)
//[SERVER A]
const request = require('request')
request('http://google.com/doodle.png').pipe(request.post('http://localhost:3000/'))
I hope you can extrapolate this for your specific use case.

Related

How to read data as buffer from an audio file as soon as it is added to the file in nodejs?

I have a .wav audio file being recorded live. I just want to read it's data as soon as the data is added to it and send to some other server (or web browser to listen live)
How can I do this in nodejs.
TL;DR: Create a read stream of your .wav file and pipe it with your write stream.
This is not an actual working example. This is just to demonstrate how you can achieve it.
Here, res is a write stream!
const fs = require('fs');
const file = fs.createReadStream('audio.wav');
app.get('/', (req, res) => {
file.on('data', (chunk) => {
// Send chunk to client
res.send(chunk); // May be?
});
});
Or, you can use pipe!
app.get('/', (req, res) => {
file.pipe(res);
});

nodejs send mp3 from another server to the client

I have an express server it grabs stuff from my other server, edits it, and sends it to the client using the curl library (I tried request but it did the same thing). Everything works great except when I try sneding an MP3 file. If I try that then Chrome can't decode the MP3. However, If I access the MP3 from the original server it decodes fine and plays. I don't edit the MP3's. Here is what my code looks like:
// server2.example.com source
const curl = require("curl");
const edit = (b, p) => {};
const express = require("express");
/* ... express app stuff ... */
app.get("*", (req, res) => {
curl.get(
"http://server1.example.com" + req.path, {},
(err, response, body) => {
if (err) return;
res.type(response.headers["content-type"]).status(response.statusCode).send(edit(body, patches));
}
);
});
app.listen(80);
Once again the file is un-edited and the exact same file as the one on server1. Here is a screenshot of what I see when visiting server1.example.com/audio.mp3 versus server2.example.com/audio.mp3:
server2.example.com/audio.mp3 screenshot
server1.example.com/audio.mp3 screenshot

Creating ReadStream From Uploaded File on Node.js

I am trying to receive a file on Node.js Express framework (via express-fileupload middleware), and then POST it directly to another server via the request package without saving it on the first device's disk and then re-reading it.
const streamifier = require('streamifier');
const fileUpload = require('express-fileupload');
app.use(fileUpload());
app.post('/upload', function(req, res) {
var fileBuffer = req.files.upload.data;
var fileReadStream = streamifier.createReadStream(fileBuffer);
//Use 'request' to send fileReadStream to another API for additional processing
}
However, the receiving API does not receive any file when I run this code.
When I run this other code, however, it works fine, but fs is only able to create a ReadStream from a file on the server, so it would involve me saving the file to some temporary hard disk location first, reading it again, and then sending it to the remote API, which I think is a bit wasteful.
var fs = require('fs');
app.post('/upload', function(req, res) {
var fileReadStream = fs.createReadStream('test.txt');
//Use 'request' to send fileReadStream to another API for additional processing
}
Any idea why the 1st code block results in no file received by the external API, while the 2nd one works perfectly fine? It seems that fileReadStream would be the same in both cases.
Turns out I should have just been sending the buffer by itself without transforming it into a ReadStream. However, I did have to add the name to it, or the receiving API wouldn't recognize that I was sending a file.
const fileUpload = require('express-fileupload');
app.use(fileUpload());
app.post('/upload', function(req, res) {
var fileBuffer = req.files.upload.data;
fileBuffer.name = 'test.png';
//Use 'request' to send fileBuffer to another API for additional processing
}

simple put request for nodejs without express

I need to be able to upload a zip file to a brightsign unit and thinking of creating a rest api which I can make a put request to send the zip file.
But the problem is that all examples I find is using frameworks such as express. Is it possible to make a rest API handling a PUT requst in nodejs without using extra frameworks?
The problem is that I can only use modules that does not need a "configuration" step on the brightsign player. So I can use modules that only contain plain javascript (I hope my explanation makes sense).
Vanilla (NodeJS HTTP API)
You will need to listen for the PUT somehow :
const http = require('http');
const querystring = require('querystring');
const server = http.createServer().listen(3000);
server.on('request', function (req, res) {
if (req.method == 'PUT') { //PUT Only
var body = '';
req.on('data', function (data){body += data;});
req.on('end', function () {
var PUT = querystring.parse(body);
console.log(PUT);
res.writeHead(200, {'Content-Type': 'text/plain'})
res.write('\n[request received successfully]\n'); res.end();
});
}else{res.end();}
});
You can test it out using curl :
curl -X PUT -d destPath=/home/usr/images -d fileName=selfie.png -d fileData=base64string localhost:3000
In express is much simpler, comment if you need an express example

Download a youtube video file in node js using ytdl

I want to make user able to download a youtube video using node-ytdl.
For example when client side make a GET request for certain route the video should be downloaded in response.
var ytdl = require('ytdl-core');
var express= require('express');
//Init App Instance
var app=express();
app.get('/video',function(req,res){
var ytstream=ytdl("https://www.youtube.com/watch?v=hgvuvdyzYFc");
ytstream.on('data',function(data){
res.write(data);
})
ytstream.on('end',function(data){
res.send();
})
})
Above is my nodejs code. Even though in network it seems to download the response it does not make user download as a file.I don't want to store any file on server.It would be great if someone could help me how to solve the issue.
res object is a writable stream so you can directly pipe the output of ytdl to res object like this -
ytdl("http://www.youtube.com/watch?v=xzjxhskd")
.on("response", response => {
// If you want to set size of file in header
res.setHeader("content-length", response.headers["content-length"]);
})
.pipe(res);
You have to also pass the headers. Try it:
app.get('/video', (req, res) => {
var url = "https://www.youtube.com/watch?v=hgvuvdyzYFc";
res.header("Content-Disposition", 'attachment; filename="Video.mp4');
ytdl(url, {format: 'mp4'}).pipe(res);
});
If someone is still getting an error just update the package to latest version by running:
npm i ytdl-core#latest
Ok, so make a string var, then add data to it on the data event. On end, send everything. Here is an example:
const ytdl = require("ytdl-core"),
app = require("express")();
app.get("/video", (req, res) => {
let data = "", vid = ytdl("https://www.youtube.com/watch?v=hgvuvdyzYFc");
vid.on("data", d => data += d);
vid.on("end", () => res.send(data));
res.header("Content-Disposition", 'attachment; filename="Video.mp4');
});

Resources