Mimic Ajax requests with Superagent - node.js

I'm using Supertest (and thus Superagent) for some API testing on a Node.js project. I have a particular route that returns different content based on the type of request. Using expressJS's req.xhr, the code will return JSON if true or issue a redirect if false. I want to account for this in my tests but I'm struggling to get Superagent to mimic an XHR GET request.
According to ExpressJS documentation, it's looking for the X-Requested-With header in the request to be set to the value XMLHttpRequest. When I try to set this header using .set('X-Requested-With', 'XMLHttpRequest') I get
Unhandled rejection Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
Odd thing is, I can set other headers, even before this one, just fine
.set('Accept', 'application/json'). If the headers have already been written, this should fail too, but it doesn't. Also, checking res.request.req._headers, it appears nothing else is setting X-Requested-With so it's not like something else gave it a value either.

Related

how to modify response status code in chrome extension?

using chrome.webRequest I can modify request or response headers, however I also need modify Response.statusCode, is it possible? I do not see anything in documentation.
https://developer.chrome.com/docs/extensions/reference/webRequest/
I see something interesting here:
https://tweak-extension.com/blog/how-to-override-http-status-code#lets-override
It seems the request is not sent but a mock response has been applied but I'm not sure how.

Why do we need to add .end() to a response?

Currently building a RESTful API with express on my web server, and some routes like the delete route for a document with mongoose ex. await Note.findByIdAndRemove(request.params.id) response.status(204).end() send response statuses with end()
Why do I need to add the .end()? What in these cases, and why cant one just send response.status(204)
With some responses that return json, the response.status(201).json works fine
Only certain methods with Express or the http interface will send the response. Some methods such as .status() or .append() or .cookie() only set state on the outgoing response that will be used when the response is actually sent - they don't actually send the response itself. So, when using those methods, you have to follow them with some method that actually sends the response such as .end().
In your specific example of:
response.status(204)
You can use the Express version that actually sends the response:
response.sendStatus(204)
If you choose to use .status() instead, then from the Express documentation, you have to follow it with some other method that causes the response to be sent. Here are examples from the Express documentation for .status():
res.status(403).end()
res.status(400).send('Bad Request')
res.status(404).sendFile('/absolute/path/to/404.png')
Since all three of these other methods will cause the response to be sent and when the response goes out, it will pick up the previously set status.

How to see the all the response headers in Node Express?

I want to see in Node Exprees enviroment all the headers that are sent to the client
But when i see do this:
app.get("/", (req, res) => {
console.log(res.getHeaders());
});
i only see this :
At the time you're looking at the outgoing headers, those are the only ones that have been added so far. The rest will be added by the code that sends the actual response or by other middleware.
If you want to see all the headers that were eventually added to the response before it was sent, you can monitor the finish event and THEN look at the headers:
app.use(function(req, res, next) {
res.on('finish', () => {
console.log(`request url = ${req.originalUrl}`);
console.log(res.getHeaders());
});
next();
});
This will sometimes not include the date, content-type or content-length headers unless they are specifically set by the sending code. This is because if these are not set by the sending code, then the HTTP library adds these headers at a lower level as it is sending the headers and thus res.getHeaders() does not retrieve them and never knows about them.
Edit: I overlooked your first screenshot... Are you using any middleware? It looks like you're using the CORS middleware, at least - which is why you are showing more headers than the defaults..
It looks like Node/Express sends a Content-Length header when it can..
The Date header is mandatory per the HTTP spec, but it looks like you can change that behavior in Node/Express - I'm guessing by default Node/Express sets that value to true.
I did test setting res.sendDate = false and the date header was not sent, so it looks like that header is set by default for you, most likely as the last step in the response?
With res.sendDate = false;
Without setting res.sendDate (aka the default):
All in all, I'm assuming the headers you don't see when you console.log(res.getHeaders()) are set by Node/Express by default..
I wasn't able to find anything in the docs about default response headers (outside of the Date header), but it's possible I overlooked something. The Express docs don't have anything on it as they just use the built in http module from Node.

NodeJS HTTP - Removing a header from request to be proxied

I have a NodeJS proxy service which obfuscates some data and forwards the request to another service. Due to some details surrounding how we, and the servcie we're proxying to handle authentication, we need to remove a certain header from the incoming request before we proxy it.
I saw some documentation about request such as: "This object is created internally and returned from http.request(). It represents an in-progress request whose header has already been queued. The header is still mutable using the setHeader(name, value), getHeader(name), removeHeader(name) API."
But then the same documentation says the headers are read-only. I also saw some documentation that showed those methods (removeHeader, etc) being available, and others that don't list it.
Can someone tell me if there's a way to remove a header from the request object itself before copying the headers over? If not is there an easy way to copy over all the headers except the one I want to leave out?
Came here looking for a solution, but for node-http-proxy. You can do it by listening to proxyReq event on the proxy and then calling removeHeader on the proxy request object, like so
myProxy.on("proxyReq", function(proxyReq, req, _, options) {
proxyReq.removeHeader("x-my-header");
});

Creating restify createJsonClient

Trying to write some mocha tests for my restify server. Some of the services require an Authorization header.
I am trying to set it this way:
var client = restify.createJsonClient({
version: '1.0.0',
url: 'http://localhost:9000',
headers: {Authorization:'Bearer ' + global.access_token}
});
but inspecting the request headers shows its not getting set, and my test is failing because of invalid credentials.
reading here, i believe i have the headers option.
http://restifyjs.com/#jsonclient
global.access_token is being set correctly.
Can someone help with some options on how to set that header?
Thanks
The header was getting set. there was a _headers node higher up in the stack and i could see that the Authorization header was getting set, but as the value:
'Bearer undefined'
So for some reason when the restify client was getting created it can not get the value from global, although its getting set in my test 01-test.
In the body of the 02-test, i can console the value and see it.
So either.
The value isn't set by the time the next test starts.
The value can't be retrieved in the restify client setup
Either way, I solved it by actually writing the token synchronously to a tmp file and reading it subsequent tests. Seems hacky, but maybe something else will come to mind.

Resources