Skip to content

Commit 0592d91

Browse files
authored
http: add drop request event for http server
PR-URL: #43806 Reviewed-By: Matteo Collina <[email protected]>
1 parent 373bbce commit 0592d91

File tree

4 files changed

+100
-1
lines changed

4 files changed

+100
-1
lines changed

doc/api/http.md

+14
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,20 @@ This event is guaranteed to be passed an instance of the {net.Socket} class,
14061406
a subclass of {stream.Duplex}, unless the user specifies a socket
14071407
type other than {net.Socket}.
14081408

1409+
### Event: `'dropRequest'`
1410+
1411+
<!-- YAML
1412+
added: REPLACEME
1413+
-->
1414+
1415+
* `request` {http.IncomingMessage} Arguments for the HTTP request, as it is in
1416+
the [`'request'`][] event
1417+
* `socket` {stream.Duplex} Network socket between the server and client
1418+
1419+
When the number of requests on a socket reaches the threshold of
1420+
`server.maxRequestsPerSocket`, the server will drop new requests
1421+
and emit `'dropRequest'` event instead, then send `503` to client.
1422+
14091423
### Event: `'request'`
14101424

14111425
<!-- YAML

lib/_http_server.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
983983
if (isRequestsLimitSet &&
984984
(server.maxRequestsPerSocket < state.requestsCount)) {
985985
handled = true;
986-
986+
server.emit('dropRequest', req, socket);
987987
res.writeHead(503);
988988
res.end();
989989
} else if (req.headers.expect !== undefined) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const http = require('http');
5+
const net = require('net');
6+
const assert = require('assert');
7+
8+
function request(socket) {
9+
socket.write('GET / HTTP/1.1\r\n');
10+
socket.write('Connection: keep-alive\r\n');
11+
socket.write('\r\n\r\n');
12+
}
13+
14+
const server = http.createServer(common.mustCall((req, res) => {
15+
res.end('ok');
16+
}));
17+
18+
server.on('dropRequest', common.mustCall((request, socket) => {
19+
assert.strictEqual(request instanceof http.IncomingMessage, true);
20+
assert.strictEqual(socket instanceof net.Socket, true);
21+
server.close();
22+
}));
23+
24+
server.listen(0, common.mustCall(() => {
25+
const socket = net.connect(server.address().port);
26+
socket.on('connect', common.mustCall(() => {
27+
request(socket);
28+
request(socket);
29+
}));
30+
socket.on('data', common.mustCallAtLeast());
31+
socket.on('close', common.mustCall());
32+
}));
33+
34+
server.maxRequestsPerSocket = 1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
if (!common.hasCrypto)
6+
common.skip('missing crypto');
7+
8+
const https = require('https');
9+
const http = require('http');
10+
const net = require('net');
11+
const assert = require('assert');
12+
const tls = require('tls');
13+
const { readKey } = require('../common/fixtures');
14+
15+
function request(socket) {
16+
socket.write('GET / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n\r\n');
17+
}
18+
19+
// https options
20+
const httpsOptions = {
21+
key: readKey('agent1-key.pem'),
22+
cert: readKey('agent1-cert.pem')
23+
};
24+
25+
const server = https.createServer(httpsOptions, common.mustCall((req, res) => {
26+
res.end('ok');
27+
}));
28+
29+
server.on('dropRequest', common.mustCall((request, socket) => {
30+
assert.strictEqual(request instanceof http.IncomingMessage, true);
31+
assert.strictEqual(socket instanceof net.Socket, true);
32+
server.close();
33+
}));
34+
35+
server.listen(0, common.mustCall(() => {
36+
const socket = tls.connect(
37+
server.address().port,
38+
{
39+
rejectUnauthorized: false
40+
},
41+
common.mustCall(() => {
42+
request(socket);
43+
request(socket);
44+
socket.on('error', common.mustNotCall());
45+
socket.on('data', common.mustCallAtLeast());
46+
socket.on('close', common.mustCall());
47+
})
48+
);
49+
}));
50+
51+
server.maxRequestsPerSocket = 1;

0 commit comments

Comments
 (0)