Is there a default timeout in Node.js for http.request? - node.js

In Node.js there is a default timeout for a server (for an incoming HTTP request) at 120000ms (2 minutes) (see HTTP's server.timeout documentation).
But if I want to do an HTTP request in Node.js (using http.request), looking at the documentation, I only find a function request.setTimeout() to set the timeout manually.
Anyone know if there is a default timeout for HTTP requests in Node.js? Or does Node.js try to send the HTTP request with no end?

You want to set the server.timeout property (it defaults to 120,000, as you've found).
Update: Node.js 13 has removed the default timeout:
https://nodejs.org/api/http.html#servertimeout
https://github.com/nodejs/node/pull/27558

I was also interested in this. By reading the code, Node.js uses Socket under the hood of http request (naturally). (The source link below is referring v8.8.0 at the point when I'm writing this)
https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js
And Socket does not have the timeout by default by this document
https://nodejs.org/dist/latest-v6.x/docs/api/net.html#net_socket_settimeout_timeout_callback
And the source tells the same.
https://github.com/nodejs/node/blob/master/lib/net.js

No. There is no default timeout.
Node.js uses Socket under the hood of http request and socket does not have the timeout by default.
Use the {timeout: XX} parameter of http.request to configure a proper request timeout.

Related

What happens if you don't end the connection in Express?

What the title says. I ran into a bug where the issue was an express endpoint not ending the request connection which caused it to seemingly hang. I am still confused how the request and response flow looks like.
The Express http server object has a configurable timeout and after that timeout with no response on the http connection, the server will close the socket.
Similarly, most http clients at the other end (such as browsers) have some sort of timeout that will likely close the TCP socket if they've been waiting for a response for too long.
The http server timeout is built into the underlying http server object that Express uses and you can see how to configure its timeout here: Express.js Response Timeout. By default, the nodejs http server timeout is set to 0 which means "no timeout" is enforced.
So, if you have no server timeout and no client timeout, then the connection will just sit there indefinitely.
You can configure your own Express timeout with:
// set server timeout to 2 minutes
server.timeout = 1000 * 60 * 2;
See doc here.
Where server is the http server object created by either http.createServer() or app.listen().

socket.io client doesn't set sid in requests

I'm trying to build a nodejs script to communicate with a socket.io server.
const io = require('socket.io-client');
const socket = io('http://192.168.144.249');
socket.on('connect', () => {
console.log('connected');
})
Using wireshark to follow traffic I can see the following:
So the browser sends me a sid, both in the response body and in the cookie.
Unfortunately, my following requests do not include this sid and I received a 400 Bad Request error:
When I try to build the same client from a browser windows I can see that this cookie is indeed set, both as cookie and as a query parameter:
I don't want to use a browser, I want to use a standalone node script. As far as I understood the parsing of the response and the inclusion of the session id should be done automatically by the socket.io-client. Am I wrong? If so, how can I intercept this event so that I can send the sid with following requests?
Am I supposed to first do a simple http request to the server, get the sid from there and then add it to the socket.io client when creating it using custom cookies or custom query parameters?
I can also see that the node standalone script is using engine.io version 4 (EIO=4 in the GET requests), while the browser is doing it with engine.io version 3, but the respose received seems to be exactly the same so I don't really think this is what is preventing my script from automatically completing the handshake with the server.
Well, I was wrong. It was indeed a protocol mismatch problem.
I was able to make my script working using socket.io-client#1.0.2. Install it with:
npm install socket.io-client#1.0.2

Setting long timeout for http request via nodejs angular4 or express

I currently have a request which is made from an angular 4 app(which uses electron[which uses chromium]) to a bottleneck(nodejs/express) server. The server takes about 10 minutes to process the request.
The default timeout which I'm getting is 120 seconds.
I tried to use setting the timeout on the server using
App.use(timeout("1000s")
In the client side I have used
options = {
url,
method: GET
timeout : 600 * 1000}
let req = http.request(options, () => {})
req.end()
I have also tried to give the specific route timeout.
Each time the request hits 120 seconds the socket dies and I get a "socket timeout"
I have read many posts with the same questions but I didn't get any concrete answers. Is it possible to do a request with a long/no timeout using the tools above? Do I need to download a new library which handles long timeouts?
Any help would be greatly appriciated.
So after browsing through the internet I have discovered that there is no possible way to increase Chrome's timeout time.
My solution to this problem was to open the request and return a default answer(something like "started") then pinging the server to find out it's status.
There is another possible solution which will be to put a route in the client(I'm using electron and node modules in the client side so it is possible) and then let the server ping back to the client with the status of the query.
Writing this down so other people will have some possible patches. Will update if I'll find anything better.

How to change the AWS node client user agent?

I'm using the node aws-sdk package and I need to send a custom user agent in the S3 requests in order to identify the process in the console log.
I've seen a method to do this in the Java SDK but I can't see any similar in the node package.
Is there any way to do this easily?
After browsing in the source code I found an undocumented option to set the user agent: customUserAgent
const options = { customUserAgent: 'my-process-name' };
const client = new AWS.S3(options);
You can define an agent in the httpoptions field of the options you send to the constructor as per here:
httpOptions (map) — A set of options to pass to the low-level HTTP request.
Currently supported options are:
proxy [String] — the URL to proxy requests through
agent [http.Agent, https.Agent] — the Agent object to perform HTTP requests with. Used for connection pooling. Defaults to the global agent (http.globalAgent) for non-SSL connections. Note that for SSL connections, a special Agent object is used in order to enable peer certificate verification. This feature is only available in the Node.js environment.
connectTimeout [Integer] — Sets the socket to timeout after failing to establish a connection with the server after connectTimeout milliseconds. This timeout has no effect once a socket connection has been established.
timeout [Integer] — Sets the socket to timeout after timeout milliseconds of inactivity on the socket. Defaults to two minutes (120000).
xhrAsync [Boolean] — Whether the SDK will send asynchronous HTTP requests. Used in the browser environment only. Set to false to send requests synchronously. Defaults to true (async on).
Is that what you're looking for?

Node server, socket, request and response timeouts

Problem
Node's default configuration timeouts requests after 2 minutes. I would like to change the request timeouts to:
1 minute for 'normal' requests
5 minutes for requests that serve static files (big assets in this case)
8 hours for uploads (couple of thousand pictures per request)
Research
Reading through Node's documentation, I've discovered that there are numerous ways of defining timeouts.
server.setTimeout
socket.setTimeout
request.setTimeout
response.setTimeout
I'm using Express which also provides middleware to define timeout's for (specific) routes. I've tried that, without success.
Question
I'm confused about how to properly configure the timeout limit globally and per route. Should I configure all of the above timeouts? How is setting the server's timeout different to setting the socket's or request's timeout?
As I saw on your other question concerning the usage of the timeout middleware, you are using it somehow differently.
See documentation of timeout-connect middleware.
Add your errorHandler-function as an EventListener to the request, as it is an EventEmitter and the middleware causes it to emit the timeout-event:
req.on("timeout", function (evt) {
if (req.timedout) {
if (!res.headersSent) {
res
.status(408)
.send({
success: true,
message: 'Timeout error'
});
}
}
});
This is called outside of the middleware stack, causing the function call to next(err) to be invalid. Also, you have to keep in mind, that if the timeout happens while the request is hanging server-side, you have to prevent your server code from further processing this request (because headers are already sent and its underlying connection will no longer be available).
Summary
nodejs timeout API are all inactivity timeout
expressjs/timeout package is response hard timeout
nodejs timeout API
server.timeout
inactivity/idle timeout
equal to socket timeout
default 2min
server.setTimeout
inactivity/idle timeout
equal to socket timeout
default 2min
have callback
socket.setTimeout
inactivity/idle timeout
callback responsible to end(), destroy() socket
default no timeout
response.setTimeout
socket.setTimeout front end
request.setTimeout
socket.setTimeout front end
expressjs/timeout package
response hard-timeout (vs inactivity)
have callback
Conclusion
max. time allowed for an action(request+response), express/timeout package is needed.
This is properly what you need, but the callback need to end the request/response. As the timeout only trigger the callback, it does not change the state or interfere with the connection. It is the callback job.
idle timeout, set nodejs api request/response timeout
I don't recommend touching these, as it is not necessary in most cases. Unless you want to allow a connection to idle(no traffic) over 2min.
There is already a Connect Middleware for Timeout support. You can try this middleware.
var timeout = express.timeout // express v3 and below
var timeout = require('connect-timeout'); //express v4
app.use(timeout(120000)); // should be changed with your desire time
app.use(haltOnTimedout);
function haltOnTimedout(req, res, next){
if (!req.timedout) next();
}

Resources