Read buffer object in node.js - javascript

I'm trying to get html page through this node module called Wreck
It should be very easy to get data but I'm unable to get them
'use strict';
var Wreck = require('wreck');
var url = 'http://www.google.it';
var callback = function(err, response, payload){
Wreck.read(response, null, function(err, body){
//here print out the html page
});
};
Wreck.get(url, callback);
Here above a simple script just a copy from the readme of the developer. according to the documentation body should return a buffer object but how can I read inside a body object? I have read to use toJSON or toString() but I don't get any result

...but I don't get any result
You ARE getting a result, an empty Buffer, but it's not want you want, probably.
The fact is: you are using the read method wrong, passing it inside a callback to the get method. The methods get, post, put and delete already call read internaly and return the readable Buffer for you, in a callback. Take a look at the get doc:
get(uri, [options], callback)
Convenience method for GET operations.
uri - The URI of the requested resource.
options - Optional config object containing settings for both request and read operations.
callback - The callback function using the signature function (err, response, payload) where:
err - Any error that may have occurred during handling of the request.
response - The HTTP Incoming Message object, which is also a readable stream.
payload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).
So, the use of the get method is pretty straightforward (using your own example):
var callback = function(err, response, payload){
console.log(payload.toString()); // converting the buffer to a string and logging
};
Wreck.get(url, callback);

Related

Node crypto.randomBytes return token from function

Summary
I have a function where I use crypto.randomBytes to generate a token and I'm having trouble returning the token from the function. I want to return token from createResetToken. My function is below and I've tried many different things but they aren't working. Any help would be greatly appreciated!
Code
function createResetToken() {
crypto.randomBytes(20, function(err, buf) {
const token = buf.toString("hex");
console.log("token inside inside", token);
return token;
});
}
Easiest way of doing this is using sync way of randomBytes(), you can make it by just not providing a callback function:
function createResetToken() {
return crypto.randomBytes(20).toString("hex");
}
By docs:
If a callback function is provided, the bytes are generated
asynchronously and the callback function is invoked with two
arguments: err and buf. If an error occurs, err will be an Error
object; otherwise it is null. The buf argument is a Buffer containing
the generated bytes.
...
If the callback function is not provided, the random bytes are
generated synchronously and returned as a Buffer. An error will be
thrown if there is a problem generating the bytes.

How to set timeout of grpc client in node.js

I'm referring to the following example of node-grpc client:
https://github.com/grpc/grpc/blob/master/examples/node/dynamic_codegen/greeter_client.js
//create a client
var client = new hello_proto.Greeter('localhost:50051',
grpc.credentials.createInsecure());
//issue the call
client.sayHello({name: user}, function(err, response) {
console.log('Greeting:', response.message);
});
In this call format, where do I provide the call deadline options.
Also, the jsdoc at https://grpc.io/grpc/node/ never has this kind of API calls.
Is there a good tutorial on this which covers examples like streaming rpcs, timeouts, securing the channels etc?
There's an optional argument to pass additional options between the request argument and the callback. This includes a deadline key. So you would do something like this:
client.sayHello({name: user}, {deadline: deadline}, function(err, response) {
console.log('Greeting:', response.message);
});
Deadline can either be a date object or Infinity to explicitly not have the call time out.
This is documented, sort of, as the Client#makeUnaryRequest function; just ignore the first three arguments. That mentions the optional options argument, and its type Client~CallOptions describes all of the options that can be passed there.

How can I get the raw request body in a Google Cloud Function?

I need the raw request body to be able to SHA-1 digest it to validate the Facebook webhook X-Hub-Signature header that's passed along with the request to my Firebase Function (running on Google Cloud Functions).
The problem is that in cases like this (with a Content-Type: application/json header) GCF automatically parses the body using bodyParser.json() which consumes the data from the stream (meaning it cannot be consumed again down the Express middleware chain) and only provides the parsed javascript object as req.body. The raw request buffer is discarded.
I have tried to provide an Express app to functions.https.onRequest(), but that seems to be run as a child app or something with the request body already being parsed, just like when you pass a plain request-response callback to onRequest().
Is there any way to disable GCF from parsing the body for me? Or could I somehow specify my own verify callback to bodyParser.json()? Or is there some other way?
PS: I first contacted Firebase support about this a week ago, but for lack of a response there I'm trying it here now.
Now you can get the raw body from req.rawBody. It returns Buffer. See documentation for more details.
Thanks to Nobuhito Kurose for posting this in comments.
Unfortunately the default middleware currently provides no way to get the raw request body. See: Access to unparsed JSON body in HTTP Functions (#36252545).
const escapeHtml = require('escape-html');
/**
* Responds to an HTTP request using data from the request body parsed according
* to the "content-type" header.
*
* #param {Object} req Cloud Function request context.
* #param {Object} res Cloud Function response context.
*/
exports.helloContent = (req, res) => {
let name;
switch (req.get('content-type')) {
// '{"name":"John"}'
case 'application/json':
({name} = req.body);
break;
// 'John', stored in a Buffer
case 'application/octet-stream':
name = req.body.toString(); // Convert buffer to a string
break;
// 'John'
case 'text/plain':
name = req.body;
break;
// 'name=John' in the body of a POST request (not the URL)
case 'application/x-www-form-urlencoded':
({name} = req.body);
break;
}
res.status(200).send(`Hello ${escapeHtml(name || 'World')}!`);
};

Why modify request after request.post

Newbie question while trying to understand code created by others. Believe me I tried to understand this. Here goes..
For what reason would someone still call functions like .qs() and .json() in Request - module after we got what we need with .post() and sent the response already. They can't affect the request.post as they are called afterwards, can they?
With my skills I'm not able to understand from response module API docs (v2.22.0) what these actually do.
This is not the whole code but I tried to get the important parts here:
// When request comes to /getthisapge, make external query and return data in JSON format.
var request = require('request');
module.exports = function(app) {
app.get('/getthispage', function(req, res, next) {
var filter = {};
var query = {};
filter.category = req.query.category;
query.onBehalf = req.query.onBehalf;
request.post(URIandoptions, function(error, response, body) {
res.json(body.members)
}).qs(query).json(filter);
}
}
Without knowing exactly what the post function does (unnecessary to your question), you need to look at the order of execution.
request.post(URIandoptions, function (error, response, body){
res.json(body.members)
})
.qs(query) // ?
.json(filter); // ?
The function passed into post() does not get called at that specific moment. It is given to the post() function to do with as it pleases. This means technically that the function may never be called (depends on the api).
qs() and json() both get called upon the returning of the prior function. Usually this type of api means the following:
call post(), passing in a function to be run on completion
call qs() to setup the query details
call json() to tell the post function how to act, which in turn executes the actual post, running the completion function after data has been retrieved.

Rendering HTML template with EJS in a callback for asynchronous fs.readFile?

I easily accomplished this with the fs.readFileSync but I want to do this asynchronously. My code follows.
function send(err, str){
if(err){
console.log(err);
}
var template = ejs.render(str, 'utf8', {name: data.name});
transporter.sendMail({
from: myEmail,
to: anotherEmail,
subject: mySubject,
html: template,
attachments: images
}, function(err, response) {
if(err){
console.log(err);
}
});
}
fs.readFile('emailTemplate.ejs', send);
So I made my own callback for fs.readFile so that when the file has been read it will render the email, putting the proper name in and then send it off with nodemailer. However, it does not like this. It gets by the error if no problem but render throws the following error when it tries to render the template.
TypeError: Object (Followed by the entire HTML of the template) has no method 'indexOf'
at Object.exports.parse (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:144:21)
at exports.compile (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:229:15)
at Object.exports.render (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:289:10)
at send (/home/ubuntu/workspace/routes/email.js:171:28)
at fs.readFile (fs.js:272:14)
at Object.oncomplete (fs.js:108:15)
Doing it synchronously works fine though.
var str = fs.readFileSync('emailTemplate.ejs', 'utf8');
var template = ejs.render(str, {
name: data.name
});
Can anyone give me any insight into why this is happening?
The documentation of fs.readFile and fs.readFileSync says
If no encoding is specified, then the raw buffer is returned.
Because you provide the encoding with the synchronous version, but do not with the asynchronous one they both differ in behaviour.
If you try this:
fs.readFile('emailTemplate.ejs', {encoding: "utf8"}, send);
it should work.
Try setting the encoding of the fs.readFile call, e.g.:
fs.readFile('emailTemplate.ejs', 'utf8', send);
When calling readFile asynchronously there is no default encoding, and instead returns the raw buffer. Currently, this buffer is being sent to the EJS render call and failing.
See the node documentation for readFile for more information.

Categories

Resources