I have a #grpc/grpc-js server. It includes a handler for a method that looks like this
server = new grpc.Server()
server.addService(proto.GrpcTester.service, {
myMethod(call, callback) {
callback(null, {hello:"world"})
}
})
Is there a way to access the HTTP2 request headers that were set when this request was made?
The call object passed to the myMethod function in that example code has a metadata property that contains the request headers.
Related
Trying to use Sinon for the first time because of its fake server functionality that lets me stub an API response. Test itself is written for Mocha
However, the fake server doesn't seem to be intercepting the requests.
Code:
describe('when integrated', function() {
var server;
beforeEach(function() {
server = sinon.createFakeServer();
});
afterEach(function() {
server.restore();
});
it('can send a message to the notification service', function() {
server.respondWith("POST", new RegExp('.*/api/notificationmanager/messages.*'),
[200,
{ "Content-Type": "application/json" },
'{ "messageId":23561}'
]);
var messageOnly = new PushMessage(initMessageObj);
var originalUrl = PushMessage.serverUrl;
messageOnly.setServerAPI("http://a.fake.server/api/notificationmanager/messages");
console.log("fake server is: ", server);
messageOnly.notify()
.then(function(response) {
messageOnly.setServerAPI(originalUrl);
return response;
})
.then(function(response) {
response.should.be.above(0);
})
console.log(server.requests);
server.respond();
})
});
For reference, PushMessage is an object that has a static property serverUrl. I'm just setting the value to a fake URL & then resetting it.
The notify() function makes a post message using request-promise-native to the serverUrl set in the PushMessage's static property.
What seems to be happening, is that the POST request ends up being properly attempted against the URL of http://a.fake.server/api/notificationmanager/messages, resulting in an error that the address doesn't exist...
Any idea what I'm doing wrong...? Thanks!
There have been several issues on the Sinon GitHub repository about this. Sinon's fake server:
Provides a fake implementation of XMLHttpRequest and provides several interfaces for manipulating objects created by it.
Also fakes native XMLHttpRequest and ActiveXObject (when available, and only for XMLHTTP progids). Helps with testing requests made with XHR.
Node doesn't use XHR requests, so Sinon doesn't work for this use case. I wish it did too.
Here's an issue that breaks it down: https://github.com/sinonjs/sinon/issues/1049
Nock is a good alternative that works with Node: https://www.npmjs.com/package/nock
With the Node JS request module it is possible to get the response, but, is there any way of getting the request headers sent?
I'm not sure what the official way of doing this is but there are several things that seem to work.
If you haven't bound the callback to another this value then it will just be the request, e.g.:
request.get(options, function() {
console.log(this.getHeader('... header name ...'));
console.log(this.headers);
});
You could also access the request using response.request:
request.get(options, function(err, response) {
console.log(response.request.getHeader('... header name ...'));
console.log(response.request.headers);
});
That second approach should work anywhere that you have access to the response.
I believe these are the relevant lines in the source code:
https://github.com/request/request/blob/253c5e507ddb95dd88622087b6387655bd0ff935/request.js#L940
https://github.com/request/request/blob/253c5e507ddb95dd88622087b6387655bd0ff935/request.js#L1314
I am using request npm module in my app, to make to create a http client, as this.
var request = require('request');
And each time, I make a request to some server, I pass the options as below:
var options = {
url: "whateverurl...",
body: { some json data for POST ... }
}
request(options, cb(e, r, body) {
// handle response here...
})
This was working fine, until I started testing with high load, and I started getting errors indicating no address available (EADDRNOTAVAIL). It looks like I am running out of ephemeral ports, as there is no pooling or keep-alive enabled.
After that, I changed it to this:
var options = {
url: "whateverurl...",
body: { some json data for POST ... },
forever: true
}
request(options, cb(e, r, body) {
// handle response here...
})
(Note the option (forever:true)
I tried looking up request module's documentation about how to set keep-alive. According to the documentation and this stackoverflow thread, I am supposed to add {forever:true} to my options.
It didn't seem to work for me, because when I checked the tcpdump, the sever was still closing the connection. So, my question is:
Am I doing something wrong here?
Should I not be setting a global option to request module, while I am "require"ing it, instead of telling it to use {forever:true}, each time I make a http request? This is confusing to me.
I have the following controller that get a file from the a service and pipes the answer to the browser.
function (req,res){
request.get(serviceUrl).pipe(res);
}
I'd like to change the content-disposition (from attachment to inline) so the browser opens the file instead of directly download it.
I already tried this, but it is not working:
function (req,res){
res.set('content-disposition','inline');
request.get(serviceUrl).pipe(res);
}
The versions I'm using are:
NodeJS: 0.12.x
Express: 4.x
To do this you can use an intermediate passtrhough stream between request and response, then headers from request won't be passed to response:
var through2 = require('through2'); // or whatever you like better
function (req, res) {
var passThrough = through2(); // this stream is necessary to put correct response headers
res.set('content-disposition','inline');
request.get(serviceUrl).pipe(passThrough).pipe(res);
}
But be carefull, as this will ignore all headers, and you will probably need to specify 'Content-Type', etc.
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
Can anyone explain me why do we call the writeHead and end
method in createServer method.
What is the main purpose of options object passed in createServer
method.
Those calls to writeHead and end are not being done in the createServermethod, but rather in a callback.
It's a bit easier to see if you split out the callback into a separate function:
function handleRequest(req, res) {
res.writeHead(200);
res.end("hello world\n");
}
https.createServer(options, handleRequest).listen(8000);
So here we define a handleRequest function and then pass that into the createServer call. Now whenever the node.js server we created receives an incoming request, it will invoke our handleRequest method.
This pattern is very common in JavaScript and is core to node.js' asynchronous event handling.
In your code, the writeHead() is called to write the header of the response, that the application will serve to the client. The end() method both sends the content of the response to the client and signals to the server that the response (header and content) has been sent completely. If you are still going to send anything else, you should call write() method of res response object instead.
The options JSON object is a modifier that you may use, to override the default behaviour of the createServer() method. In your code's case:
+ key: Private key to use for SSL (default is null)
+ cert: Public x509 certificate to use (default is null)
You can find more in this section of the Node.js API doc about the response.writeHead() method.
You can find more in this section of the Node.js API doc about the https.createServer() method.
response.writeHead(200) sends a response header to the request. The status code is a 3-digit HTTP status code, like 404.
This method must only be called once on a message and it must be called before response.end() is called.
If you call response.write() or response.end() before calling this, the implicit/mutable headers will be calculated and call this function for you.
As far as i know if you don't put the response.end() at the end then your web page will go on loading thus the response.end() is used to tell the server that the data has been loaded
The res.writeHead method is for returning a status code to the browser, and the browser will throw an error if it is a client-side status code or server-side status code. The res.end method is to make sure the response isn't returned before it might be ready, in case of nested code or otherwise.
The purpose of the options object is to make sure the page has a valid key and certificate before declaring that the page is encrypted under https.