570 lines
13 KiB
JavaScript
570 lines
13 KiB
JavaScript
'use strict'
|
|
|
|
var assert = require('node:assert')
|
|
const { Buffer } = require('node:buffer');
|
|
var express = require('..');
|
|
var methods = require('../lib/utils').methods;
|
|
var request = require('supertest');
|
|
var utils = require('./support/utils');
|
|
|
|
var shouldSkipQuery = require('./support/utils').shouldSkipQuery
|
|
|
|
describe('res', function(){
|
|
describe('.send()', function(){
|
|
it('should set body to ""', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send();
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(200, '', done);
|
|
})
|
|
})
|
|
|
|
describe('.send(null)', function(){
|
|
it('should set body to ""', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send(null);
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Length', '0')
|
|
.expect(200, '', done);
|
|
})
|
|
})
|
|
|
|
describe('.send(undefined)', function(){
|
|
it('should set body to ""', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send(undefined);
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(200, '', done);
|
|
})
|
|
})
|
|
|
|
describe('.send(Number)', function(){
|
|
it('should send as application/json', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send(1000);
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Type', 'application/json; charset=utf-8')
|
|
.expect(200, '1000', done)
|
|
})
|
|
})
|
|
|
|
describe('.send(String)', function(){
|
|
it('should send as html', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send('<p>hey</p>');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Type', 'text/html; charset=utf-8')
|
|
.expect(200, '<p>hey</p>', done);
|
|
})
|
|
|
|
it('should set ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
var str = Array(1000).join('-');
|
|
res.send(str);
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')
|
|
.expect(200, done);
|
|
})
|
|
|
|
it('should not override Content-Type', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.set('Content-Type', 'text/plain').send('hey');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Type', 'text/plain; charset=utf-8')
|
|
.expect(200, 'hey', done);
|
|
})
|
|
|
|
it('should override charset in Content-Type', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.set('Content-Type', 'text/plain; charset=iso-8859-1').send('hey');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Type', 'text/plain; charset=utf-8')
|
|
.expect(200, 'hey', done);
|
|
})
|
|
|
|
it('should keep charset in Content-Type for Buffers', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.set('Content-Type', 'text/plain; charset=iso-8859-1').send(Buffer.from('hi'))
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Type', 'text/plain; charset=iso-8859-1')
|
|
.expect(200, 'hi', done);
|
|
})
|
|
})
|
|
|
|
describe('.send(Buffer)', function(){
|
|
it('should send as octet-stream', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send(Buffer.from('hello'))
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(200)
|
|
.expect('Content-Type', 'application/octet-stream')
|
|
.expect(utils.shouldHaveBody(Buffer.from('hello')))
|
|
.end(done)
|
|
})
|
|
|
|
it('should set ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
res.send(Buffer.alloc(999, '-'))
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')
|
|
.expect(200, done);
|
|
})
|
|
|
|
it('should not override Content-Type', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.set('Content-Type', 'text/plain').send(Buffer.from('hey'))
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Type', 'text/plain; charset=utf-8')
|
|
.expect(200, 'hey', done);
|
|
})
|
|
|
|
it('should accept Uint8Array', function(done){
|
|
var app = express();
|
|
app.use(function(req, res){
|
|
const encodedHey = new TextEncoder().encode("hey");
|
|
res.set("Content-Type", "text/plain").send(encodedHey);
|
|
})
|
|
|
|
request(app)
|
|
.get("/")
|
|
.expect("Content-Type", "text/plain; charset=utf-8")
|
|
.expect(200, "hey", done);
|
|
})
|
|
|
|
it('should not override ETag', function (done) {
|
|
var app = express()
|
|
|
|
app.use(function (req, res) {
|
|
res.type('text/plain').set('ETag', '"foo"').send(Buffer.from('hey'))
|
|
})
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', '"foo"')
|
|
.expect(200, 'hey', done)
|
|
})
|
|
})
|
|
|
|
describe('.send(Object)', function(){
|
|
it('should send as application/json', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send({ name: 'tobi' });
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('Content-Type', 'application/json; charset=utf-8')
|
|
.expect(200, '{"name":"tobi"}', done)
|
|
})
|
|
})
|
|
|
|
describe('when the request method is HEAD', function(){
|
|
it('should ignore the body', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send('yay');
|
|
});
|
|
|
|
request(app)
|
|
.head('/')
|
|
.expect(200)
|
|
.expect(utils.shouldNotHaveBody())
|
|
.end(done)
|
|
})
|
|
})
|
|
|
|
describe('when .statusCode is 204', function(){
|
|
it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.status(204).set('Transfer-Encoding', 'chunked').send('foo');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(utils.shouldNotHaveHeader('Content-Type'))
|
|
.expect(utils.shouldNotHaveHeader('Content-Length'))
|
|
.expect(utils.shouldNotHaveHeader('Transfer-Encoding'))
|
|
.expect(204, '', done);
|
|
})
|
|
})
|
|
|
|
describe('when .statusCode is 205', function () {
|
|
it('should strip Transfer-Encoding field and body, set Content-Length', function (done) {
|
|
var app = express()
|
|
|
|
app.use(function (req, res) {
|
|
res.status(205).set('Transfer-Encoding', 'chunked').send('foo')
|
|
})
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(utils.shouldNotHaveHeader('Transfer-Encoding'))
|
|
.expect('Content-Length', '0')
|
|
.expect(205, '', done)
|
|
})
|
|
})
|
|
|
|
describe('when .statusCode is 304', function(){
|
|
it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.status(304).set('Transfer-Encoding', 'chunked').send('foo');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(utils.shouldNotHaveHeader('Content-Type'))
|
|
.expect(utils.shouldNotHaveHeader('Content-Length'))
|
|
.expect(utils.shouldNotHaveHeader('Transfer-Encoding'))
|
|
.expect(304, '', done);
|
|
})
|
|
})
|
|
|
|
it('should always check regardless of length', function(done){
|
|
var app = express();
|
|
var etag = '"asdf"';
|
|
|
|
app.use(function(req, res, next){
|
|
res.set('ETag', etag);
|
|
res.send('hey');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.set('If-None-Match', etag)
|
|
.expect(304, done);
|
|
})
|
|
|
|
it('should respond with 304 Not Modified when fresh', function(done){
|
|
var app = express();
|
|
var etag = '"asdf"';
|
|
|
|
app.use(function(req, res){
|
|
var str = Array(1000).join('-');
|
|
res.set('ETag', etag);
|
|
res.send(str);
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.set('If-None-Match', etag)
|
|
.expect(304, done);
|
|
})
|
|
|
|
it('should not perform freshness check unless 2xx or 304', function(done){
|
|
var app = express();
|
|
var etag = '"asdf"';
|
|
|
|
app.use(function(req, res, next){
|
|
res.status(500);
|
|
res.set('ETag', etag);
|
|
res.send('hey');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.set('If-None-Match', etag)
|
|
.expect('hey')
|
|
.expect(500, done);
|
|
})
|
|
|
|
it('should not support jsonp callbacks', function(done){
|
|
var app = express();
|
|
|
|
app.use(function(req, res){
|
|
res.send({ foo: 'bar' });
|
|
});
|
|
|
|
request(app)
|
|
.get('/?callback=foo')
|
|
.expect('{"foo":"bar"}', done);
|
|
})
|
|
|
|
it('should be chainable', function (done) {
|
|
var app = express()
|
|
|
|
app.use(function (req, res) {
|
|
assert.equal(res.send('hey'), res)
|
|
})
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(200, 'hey', done)
|
|
})
|
|
|
|
describe('"etag" setting', function () {
|
|
describe('when enabled', function () {
|
|
it('should send ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
res.send('kajdslfkasdf');
|
|
});
|
|
|
|
app.enable('etag');
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', 'W/"c-IgR/L5SF7CJQff4wxKGF/vfPuZ0"')
|
|
.expect(200, done);
|
|
});
|
|
|
|
methods.forEach(function (method) {
|
|
if (method === 'connect') return;
|
|
|
|
it('should send ETag in response to ' + method.toUpperCase() + ' request', function (done) {
|
|
if (method === 'query' && shouldSkipQuery(process.versions.node)) {
|
|
this.skip()
|
|
}
|
|
var app = express();
|
|
|
|
app[method]('/', function (req, res) {
|
|
res.send('kajdslfkasdf');
|
|
});
|
|
|
|
request(app)
|
|
[method]('/')
|
|
.expect('ETag', 'W/"c-IgR/L5SF7CJQff4wxKGF/vfPuZ0"')
|
|
.expect(200, done);
|
|
})
|
|
});
|
|
|
|
it('should send ETag for empty string response', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
res.send('');
|
|
});
|
|
|
|
app.enable('etag');
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', 'W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"')
|
|
.expect(200, done);
|
|
})
|
|
|
|
it('should send ETag for long response', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
var str = Array(1000).join('-');
|
|
res.send(str);
|
|
});
|
|
|
|
app.enable('etag');
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', 'W/"3e7-qPnkJ3CVdVhFJQvUBfF10TmVA7g"')
|
|
.expect(200, done);
|
|
});
|
|
|
|
it('should not override ETag when manually set', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
res.set('etag', '"asdf"');
|
|
res.send('hello!');
|
|
});
|
|
|
|
app.enable('etag');
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', '"asdf"')
|
|
.expect(200, done);
|
|
});
|
|
|
|
it('should not send ETag for res.send()', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
res.send();
|
|
});
|
|
|
|
app.enable('etag');
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(utils.shouldNotHaveHeader('ETag'))
|
|
.expect(200, done);
|
|
})
|
|
});
|
|
|
|
describe('when disabled', function () {
|
|
it('should send no ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.use(function (req, res) {
|
|
var str = Array(1000).join('-');
|
|
res.send(str);
|
|
});
|
|
|
|
app.disable('etag');
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(utils.shouldNotHaveHeader('ETag'))
|
|
.expect(200, done);
|
|
});
|
|
|
|
it('should send ETag when manually set', function (done) {
|
|
var app = express();
|
|
|
|
app.disable('etag');
|
|
|
|
app.use(function (req, res) {
|
|
res.set('etag', '"asdf"');
|
|
res.send('hello!');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', '"asdf"')
|
|
.expect(200, done);
|
|
});
|
|
});
|
|
|
|
describe('when "strong"', function () {
|
|
it('should send strong ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.set('etag', 'strong');
|
|
|
|
app.use(function (req, res) {
|
|
res.send('hello, world!');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', '"d-HwnTDHB9U/PRbFMN1z1wps51lqk"')
|
|
.expect(200, done);
|
|
})
|
|
})
|
|
|
|
describe('when "weak"', function () {
|
|
it('should send weak ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.set('etag', 'weak');
|
|
|
|
app.use(function (req, res) {
|
|
res.send('hello, world!');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', 'W/"d-HwnTDHB9U/PRbFMN1z1wps51lqk"')
|
|
.expect(200, done)
|
|
})
|
|
})
|
|
|
|
describe('when a function', function () {
|
|
it('should send custom ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.set('etag', function (body, encoding) {
|
|
var chunk = !Buffer.isBuffer(body)
|
|
? Buffer.from(body, encoding)
|
|
: body;
|
|
assert.strictEqual(chunk.toString(), 'hello, world!')
|
|
return '"custom"';
|
|
});
|
|
|
|
app.use(function (req, res) {
|
|
res.send('hello, world!');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect('ETag', '"custom"')
|
|
.expect(200, done);
|
|
})
|
|
|
|
it('should not send falsy ETag', function (done) {
|
|
var app = express();
|
|
|
|
app.set('etag', function (body, encoding) {
|
|
return undefined;
|
|
});
|
|
|
|
app.use(function (req, res) {
|
|
res.send('hello, world!');
|
|
});
|
|
|
|
request(app)
|
|
.get('/')
|
|
.expect(utils.shouldNotHaveHeader('ETag'))
|
|
.expect(200, done);
|
|
})
|
|
})
|
|
})
|
|
})
|