Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Verify request payload is uploaded consistently #44801

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions test/known_issues/test-http-clientrequest-end-contentlength.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For new known-issue tests, there should a comment pointing to an open issue discussing the issue and it's very helpful to add a comment explaining why the test should be expected to fail.

// Test that ClientRequest#end with default options
// computes and sends a Content-Length header
const upload = 'PUT / HTTP/1.1\r\n\r\n';
const response = 'content-length: 19\r\n';

// Test that the upload is properly received with the same headers,
// regardless of request method
const methods = [ 'GET', 'HEAD', 'DELETE', 'POST', 'PATCH', 'PUT', 'OPTIONS' ];

const server = http.createServer(common.mustCall(function(req, res) {
req.on('data', function(chunk) {
assert.strictEqual(chunk, Buffer.from(upload));
});
res.setHeader('Content-Type', 'text/plain');
let payload = `${req.method}\r\n`;
for (let i = 0; i < req.rawHeaders.length; i += 2) {
// Ignore a couple headers that may vary
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
payload += `${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`;
}
res.end(payload);
}), methods.length);

server.listen(0, function tryNextRequest() {
const method = methods.pop();
if (method === undefined) return;
const port = server.address().port;
const req = http.request({ method, port }, function(res) {
const chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
const received = Buffer.concat(chunks).toString();
const expected = method.toLowerCase() + '\r\n' + response;
assert.strictEqual(received.toLowerCase(), expected);
tryNextRequest();
});
});

req.end(upload);
}).unref();
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');

// Test that ClientRequest#end with default options
// and empty payload sends neither Content-Length nor Transfer-Encoding.
// Sending Content-Length: 0 would be acceptable, but is unnecessary.
const upload = 'PUT / HTTP/1.1\r\n\r\n';
const response = '';

// Test that the upload is properly received with the same headers,
// regardless of request method.
const methods = [ 'GET', 'HEAD', 'DELETE', 'POST', 'PATCH', 'PUT', 'OPTIONS' ];

const server = http.createServer(common.mustCall(function(req, res) {
req.on('data', function(chunk) {
assert.strictEqual(chunk.toString(), upload);
});
res.setHeader('Content-Type', 'text/plain');
res.write(`${req.method}\r\n`);
for (let i = 0; i < req.rawHeaders.length; i += 2) {
// Ignore a couple headers that may vary
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
res.write(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`);
}
res.end();
}), methods.length);

server.listen(0, function tryNextRequest() {
const method = methods.pop();
if (method === undefined) return;
const port = server.address().port;
const req = http.request({ method, port }, function(res) {
const chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
const received = Buffer.concat(chunks).toString();
const expected = method.toLowerCase() + '\r\n' + response;
assert.strictEqual(received.toLowerCase(), expected);
tryNextRequest();
});
});

req.end();
}).unref();
49 changes: 49 additions & 0 deletions test/known_issues/test-http-clientrequest-write-chunked.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');

// Test that ClientRequest#write with default options
// uses a chunked Transfer-Encoding
const upload = 'PUT / HTTP/1.1\r\n\r\n';
const response = 'transfer-encoding: chunked\r\n';

// Test that the upload is properly received with the same headers,
// regardless of request method.
const methods = [ 'GET', 'HEAD', 'DELETE', 'POST', 'PATCH', 'PUT', 'OPTIONS' ];

const server = http.createServer(common.mustCall(function(req, res) {
req.on('data', function(chunk) {
assert.strictEqual(chunk.toString(), upload);
});
res.setHeader('Content-Type', 'text/plain');
res.write(`${req.method}\r\n`);
for (let i = 0; i < req.rawHeaders.length; i += 2) {
// Ignore a couple headers that may vary
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
res.write(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`);
}
res.end();
}), methods.length);

server.listen(0, function tryNextRequest() {
const method = methods.pop();
if (method === undefined) return;
const port = server.address().port;
const req = http.request({ method, port }, function(res) {
const chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
const received = Buffer.concat(chunks).toString();
const expected = method.toLowerCase() + '\r\n' + response;
assert.strictEqual(received.toLowerCase(), expected);
tryNextRequest();
});
});

req.write(upload);
req.end();
}).unref();
30 changes: 30 additions & 0 deletions test/known_issues/test-http-request-method-delete-payload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';
const common = require('../common');

const assert = require('assert');
const http = require('http');

const data = 'PUT / HTTP/1.1\r\n\r\n';

const server = http.createServer(common.mustCall(function(req, res) {
req.on('data', function(chunk) {
assert.strictEqual(chunk, Buffer.from(data));
});
res.setHeader('Content-Type', 'text/plain');
for (let i = 0; i < req.rawHeaders.length; i += 2) {
if (req.rawHeaders[i].toLowerCase() === 'host') continue;
if (req.rawHeaders[i].toLowerCase() === 'connection') continue;
res.write(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}\r\n`);
}
res.end();
})).unref();

server.listen(0, common.mustCall(() => {
const port = server.address().port;
const req = http.request({ method: 'DELETE', port }, function(res) {
res.resume();
});

req.write(data);
req.end();
}));
Loading