npm request conditional piping based on response - node.js

I need to download a file by POSTing to a REST server.
I was first using http when it was get. But now i need to use POST, and node's http post is way too complicated, I dont want to build a low level request, so I dont want to use it.
I am now using request. https://www.npmjs.com/package/request
Now, my server either sends {isUpdateAvailable:false} or it sends a tar file.
So i need to save the file, or show 'Already up to date'. How do I pipe to a filestream by checking the response header?
I need to set the pipe along with the request code, so I'm not able to separate the code properly. I need to fs.createWriteStream only if its necessary. Will it be possible?
So, how do i do it?

Related

Express: How to get http request’s raw buffer

My application is running an Express http server. I need to save the whole http request message (headers, body,..) in its raw format just as was sent by the client to the server. I can’t find Where it is stored. Any one?
The whole thing isn't stored anywhere. Express uses the http module in node.js which parses the incoming request and headers into a data structure. The body of the request (like for a POST or a PUT) is left to you to read from the incoming readstream so you can certainly read the exact body yourself. Just hook up a listener for the data event on the incoming request stream and you can read the exact bytes of the body right into a Buffer object.
You could reconstitute the http command line and all the headers if you want from the data structure, but I don't think that original data is stored exactly as it arrived.
Some of the information is in these properties as documented here:
request.rawHeaders
request.method
request.httpVersion
request.headers
request.url
If you can explain exactly what the actual problem is that you're trying to solve, we'd have a better idea exactly how else to help you.

How to use azure logic app action to download files in browser

I originally created a logic app that would, given a JSON payload, run a stored procedure, transform the results into a CSV table and then email the CSV to a specified email account. Unfortunately requirements changed slightly and instead of emailing the csv they want it to download directly in the browser.
I am unable to get the HTTP response action to tell the browser to download the file using the Content-Disposition header. It looks like this is pulled out of the request by design. Is anyone aware of another action (perhaps a function?) that could be used in place of the HTTP response to get a web browser to download the file rather than returning it as text in the response body?
It does indeed seem to be the case that the Response action doesn't support the Content-Disposition header for some reason. Probably the easiest workround is to proxy the request through a simple HTTP-triggered Azure Function with CORS enabled (or an API on your server) that just fetches the file from the Logic App and then returns it with the Content-Disposition header attached.
NB. Don't rely on <a download="filename"> - most browsers that support the download attribute only respect it for same-origin requests.

Send json data (asynchronous) to my response

So,upon request I respond with a basic template(I use ejs) and I want to add json data to it when I get from an external API.
I have noticed that I can't use res.render or res.write twice(I get errors) so I really don't know what to do.Any ideas?
You can only send one response for each request. So you either need to do two requests or combine the data you want to send into one response.

With ExpressJS or Node, Is there an easy way to read an external image into memory and serve it?

I'm using an external service to create images. I'd like my users to be able to hit my API and ask for the image. Then my Express server would retrieve it from the external service, then serve it to the user. Sort of like a proxy I suppose, but not exactly.
Is there an easy way to do this, preferably one that doesn't involve downloading the image to the hard drive, then reading it back in and serving it?
Using the request library, I was able to come up with this:
var request = require("request");
exports.relayImage = function(req, res){
request(req.params.url).pipe(res);
}
That seems to work. If there is a more efficient way to do this (meaning on server resources, not in terms of lines of code), speak up!
What you are doing is exactly what you should be doing, and is the most efficient method. Using pipe, the data is sent as it comes in, requiring no additional resources than are needed to buffer and transmit.
Also be mindful of content type and other response headers that you may want to relay. Finally, realize that you've effectively built an open proxy where anyone can request anything they want through your servers. This is a bit dangerous, so be sure to lock it down in your final application.
You should be able to use the http module to make a request to the external image service with a callback that returns the image as the response. It won't write to disk unless you explicitly tell it to.

How to send files with node.js

How do you send files on node.js/express.
I am using Rackspace Cloudfiles and wanna send images/videos to their remote storage but I am not sure that it's as simple as reading the file (fs.readFileSync()) and send the data in the request body, or is it?
What should the headers be.
What if it's a very large file on a couple of GBs?
Is it possible to use superagent (http://visionmedia.github.com/superagent) for this or is there a better library for sending files?
Please give me some information about this.
Thanks!
app.get('/img/bg.png', function(req, res) {
res.sendFile('public/img/background.png')
})
https://expressjs.com/en/api.html#res.sendFile
use "res.sendFile". "res.sendfile" is deprecated.
For large files, you will want to use node.js's concept of piping IO streams together. You want to open the local file for reading, start the HTTP request to rackspace, and then pipe the data events from the file read process to the HTTP request process.
Here's an article on how to do this.
Superagent is fine for small files, but because the superagent API presumes your entire request body is loaded into memory before starting the request, it's not the best approach for large file transfers.
Normally you won't need to worry specifically about the request headers as node's HTTP request library will send the appropriate headers for you. Just make sure you use whatever HTTP method your API requires (probably POST), and it looks like for rackspace you will need to add the X-Auth-Token extra header with your API token as well.
I am using Rackspace Cloudfiles and wanna send images/videos to their remote storage but I am not sure that it's as simple as reading the file (fs.readFileSync()) and send the data in the request body, or is it?
You should never use fs.readFileSync in general. When you use it, or any other method called somethingSync, you block the entire server for the duration of that call. The only acceptable time to make synchronous calls in a node.js program is during startup.
What should the headers be.
See RackSpace Cloud Files API.
Is it possible to use superagent (http://visionmedia.github.com/superagent) for this or is there a better library for sending files?
While I don't have any experience with superagent, I'm sure it will work fine. Just make sure you read the API documentation and make your requests according to their specification.

Resources