Skip to content

Commit 578868d

Browse files
awwright98lenviaduh95
authored andcommitted
test: verify request payload is uploaded consistently
Node.js seems to change how it is uploaded based on the method, but HTTP doesn't make any distinction. Co-authored-by: Austin Wright <aaa@bzfx.net> Co-authored-by: Lenvin Gonsalves <lenvingonsalves@gmail.com> Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: #34066 Refs: #27880 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent fc568b4 commit 578868d

4 files changed

+185
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict';
2+
3+
// Refs: https://github.com/nodejs/node/pull/34066
4+
5+
const common = require('../common');
6+
const assert = require('assert');
7+
const http = require('http');
8+
9+
// Test that ClientRequest#end with default options
10+
// computes and sends a Content-Length header
11+
const upload = 'PUT / HTTP/1.1\r\n\r\n';
12+
const response = 'content-length: 19\r\n';
13+
14+
// Test that the upload is properly received with the same headers,
15+
// regardless of request method
16+
const methods = [ 'GET', 'HEAD', 'DELETE', 'POST', 'PATCH', 'PUT', 'OPTIONS' ];
17+
18+
const server = http.createServer(common.mustCall(function(req, res) {
19+
req.on('data', function(chunk) {
20+
assert.strictEqual(chunk, Buffer.from(upload));
21+
});
22+
res.setHeader('Content-Type', 'text/plain');
23+
let payload = `${req.method}\r\n`;
24+
for (let i = 0; i < req.rawHeaders.length; i += 2) {
25+
// Ignore a couple headers that may vary
26+
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
27+
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
28+
payload += `${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`;
29+
}
30+
res.end(payload);
31+
}), methods.length);
32+
33+
server.listen(0, function tryNextRequest() {
34+
const method = methods.pop();
35+
if (method === undefined) return;
36+
const port = server.address().port;
37+
const req = http.request({ method, port }, function(res) {
38+
const chunks = [];
39+
res.on('data', function(chunk) {
40+
chunks.push(chunk);
41+
});
42+
res.on('end', function() {
43+
const received = Buffer.concat(chunks).toString();
44+
const expected = method.toLowerCase() + '\r\n' + response;
45+
assert.strictEqual(received.toLowerCase(), expected);
46+
tryNextRequest();
47+
});
48+
});
49+
50+
req.end(upload);
51+
}).unref();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
3+
// Refs: https://github.com/nodejs/node/pull/34066
4+
5+
const common = require('../common');
6+
const assert = require('assert');
7+
const http = require('http');
8+
9+
// Test that ClientRequest#end with default options
10+
// and empty payload sends neither Content-Length nor Transfer-Encoding.
11+
// Sending Content-Length: 0 would be acceptable, but is unnecessary.
12+
const upload = 'PUT / HTTP/1.1\r\n\r\n';
13+
const response = '';
14+
15+
// Test that the upload is properly received with the same headers,
16+
// regardless of request method.
17+
const methods = [ 'GET', 'HEAD', 'DELETE', 'POST', 'PATCH', 'PUT', 'OPTIONS' ];
18+
19+
const server = http.createServer(common.mustCall(function(req, res) {
20+
req.on('data', function(chunk) {
21+
assert.strictEqual(chunk.toString(), upload);
22+
});
23+
res.setHeader('Content-Type', 'text/plain');
24+
res.write(`${req.method}\r\n`);
25+
for (let i = 0; i < req.rawHeaders.length; i += 2) {
26+
// Ignore a couple headers that may vary
27+
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
28+
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
29+
res.write(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`);
30+
}
31+
res.end();
32+
}), methods.length);
33+
34+
server.listen(0, function tryNextRequest() {
35+
const method = methods.pop();
36+
if (method === undefined) return;
37+
const port = server.address().port;
38+
const req = http.request({ method, port }, function(res) {
39+
const chunks = [];
40+
res.on('data', function(chunk) {
41+
chunks.push(chunk);
42+
});
43+
res.on('end', function() {
44+
const received = Buffer.concat(chunks).toString();
45+
const expected = method.toLowerCase() + '\r\n' + response;
46+
assert.strictEqual(received.toLowerCase(), expected);
47+
tryNextRequest();
48+
});
49+
});
50+
51+
req.end();
52+
}).unref();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
3+
// Refs: https://github.com/nodejs/node/pull/34066
4+
5+
const common = require('../common');
6+
const assert = require('assert');
7+
const http = require('http');
8+
9+
// Test that ClientRequest#write with default options
10+
// uses a chunked Transfer-Encoding
11+
const upload = 'PUT / HTTP/1.1\r\n\r\n';
12+
const response = 'transfer-encoding: chunked\r\n';
13+
14+
// Test that the upload is properly received with the same headers,
15+
// regardless of request method.
16+
const methods = [ 'GET', 'HEAD', 'DELETE', 'POST', 'PATCH', 'PUT', 'OPTIONS' ];
17+
18+
const server = http.createServer(common.mustCall(function(req, res) {
19+
req.on('data', function(chunk) {
20+
assert.strictEqual(chunk.toString(), upload);
21+
});
22+
res.setHeader('Content-Type', 'text/plain');
23+
res.write(`${req.method}\r\n`);
24+
for (let i = 0; i < req.rawHeaders.length; i += 2) {
25+
// Ignore a couple headers that may vary
26+
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
27+
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
28+
res.write(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`);
29+
}
30+
res.end();
31+
}), methods.length);
32+
33+
server.listen(0, function tryNextRequest() {
34+
const method = methods.pop();
35+
if (method === undefined) return;
36+
const port = server.address().port;
37+
const req = http.request({ method, port }, function(res) {
38+
const chunks = [];
39+
res.on('data', function(chunk) {
40+
chunks.push(chunk);
41+
});
42+
res.on('end', function() {
43+
const received = Buffer.concat(chunks).toString();
44+
const expected = method.toLowerCase() + '\r\n' + response;
45+
assert.strictEqual(received.toLowerCase(), expected);
46+
tryNextRequest();
47+
});
48+
});
49+
50+
req.write(upload);
51+
req.end();
52+
}).unref();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
const assert = require('assert');
5+
const http = require('http');
6+
7+
const data = 'PUT / HTTP/1.1\r\n\r\n';
8+
9+
const server = http.createServer(common.mustCall(function(req, res) {
10+
req.on('data', function(chunk) {
11+
assert.strictEqual(chunk, Buffer.from(data));
12+
});
13+
res.setHeader('Content-Type', 'text/plain');
14+
for (let i = 0; i < req.rawHeaders.length; i += 2) {
15+
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
16+
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
17+
res.write(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`);
18+
}
19+
res.end();
20+
})).unref();
21+
22+
server.listen(0, common.mustCall(() => {
23+
const port = server.address().port;
24+
const req = http.request({ method: 'DELETE', port }, function(res) {
25+
res.resume();
26+
});
27+
28+
req.write(data);
29+
req.end();
30+
}));

0 commit comments

Comments
 (0)