commit
eb443d1bee
10 changed files with 175 additions and 28 deletions
|
@ -171,6 +171,8 @@ koa uses [http-assert](https://github.com/jshttp/http-assert) for assertions.
|
||||||
- `ctx.body=`
|
- `ctx.body=`
|
||||||
- `ctx.status`
|
- `ctx.status`
|
||||||
- `ctx.status=`
|
- `ctx.status=`
|
||||||
|
- `ctx.message`
|
||||||
|
- `ctx.message=`
|
||||||
- `ctx.length=`
|
- `ctx.length=`
|
||||||
- `ctx.length`
|
- `ctx.length`
|
||||||
- `ctx.type=`
|
- `ctx.type=`
|
||||||
|
|
|
@ -83,6 +83,15 @@ __NOTE__: don't worry too much about memorizing these strings,
|
||||||
if you have a typo an error will be thrown, displaying this list
|
if you have a typo an error will be thrown, displaying this list
|
||||||
so you can make a correction.
|
so you can make a correction.
|
||||||
|
|
||||||
|
### response.message
|
||||||
|
|
||||||
|
Get response status message. By default, `response.message` is
|
||||||
|
associated with `response.status`.
|
||||||
|
|
||||||
|
### response.message=
|
||||||
|
|
||||||
|
Set response status message to the given value.
|
||||||
|
|
||||||
### response.length=
|
### response.length=
|
||||||
|
|
||||||
Set response Content-Length to the given value.
|
Set response Content-Length to the given value.
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
var debug = require('debug')('koa:application');
|
var debug = require('debug')('koa:application');
|
||||||
var Emitter = require('events').EventEmitter;
|
var Emitter = require('events').EventEmitter;
|
||||||
|
var onFinished = require('on-finished');
|
||||||
|
var response = require('./response');
|
||||||
var compose = require('koa-compose');
|
var compose = require('koa-compose');
|
||||||
var isJSON = require('koa-is-json');
|
var isJSON = require('koa-is-json');
|
||||||
var response = require('./response');
|
|
||||||
var context = require('./context');
|
var context = require('./context');
|
||||||
var request = require('./request');
|
var request = require('./request');
|
||||||
var onFinished = require('on-finished');
|
var statuses = require('statuses');
|
||||||
var Cookies = require('cookies');
|
var Cookies = require('cookies');
|
||||||
var accepts = require('accepts');
|
var accepts = require('accepts');
|
||||||
var status = require('statuses');
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var Stream = require('stream');
|
var Stream = require('stream');
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
|
@ -187,7 +187,7 @@ function *respond(next) {
|
||||||
var code = this.status;
|
var code = this.status;
|
||||||
|
|
||||||
// ignore body
|
// ignore body
|
||||||
if (status.empty[code]) {
|
if (statuses.empty[code]) {
|
||||||
// strip headers
|
// strip headers
|
||||||
this.body = null;
|
this.body = null;
|
||||||
return res.end();
|
return res.end();
|
||||||
|
@ -201,7 +201,7 @@ function *respond(next) {
|
||||||
// status body
|
// status body
|
||||||
if (null == body) {
|
if (null == body) {
|
||||||
this.type = 'text';
|
this.type = 'text';
|
||||||
body = status[code];
|
body = this.message || String(code);
|
||||||
if (body) this.length = Buffer.byteLength(body);
|
if (body) this.length = Buffer.byteLength(body);
|
||||||
return res.end(body);
|
return res.end(body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
var createError = require('http-errors');
|
var createError = require('http-errors');
|
||||||
var httpAssert = require('http-assert');
|
var httpAssert = require('http-assert');
|
||||||
var delegate = require('delegates');
|
var delegate = require('delegates');
|
||||||
|
var statuses = require('statuses');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var http = require('http');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context prototype.
|
* Context prototype.
|
||||||
|
@ -126,10 +126,10 @@ var proto = module.exports = {
|
||||||
if ('ENOENT' == err.code) err.status = 404;
|
if ('ENOENT' == err.code) err.status = 404;
|
||||||
|
|
||||||
// default to 500
|
// default to 500
|
||||||
if ('number' != typeof err.status || !http.STATUS_CODES[err.status]) err.status = 500;
|
if ('number' != typeof err.status || !statuses[err.status]) err.status = 500;
|
||||||
|
|
||||||
// respond
|
// respond
|
||||||
var code = http.STATUS_CODES[err.status];
|
var code = statuses[err.status];
|
||||||
var msg = err.expose ? err.message : code;
|
var msg = err.expose ? err.message : code;
|
||||||
this.status = err.status;
|
this.status = err.status;
|
||||||
this.length = Buffer.byteLength(msg);
|
this.length = Buffer.byteLength(msg);
|
||||||
|
@ -148,6 +148,7 @@ delegate(proto, 'response')
|
||||||
.method('vary')
|
.method('vary')
|
||||||
.method('set')
|
.method('set')
|
||||||
.access('status')
|
.access('status')
|
||||||
|
.access('message')
|
||||||
.access('body')
|
.access('body')
|
||||||
.access('length')
|
.access('length')
|
||||||
.access('type')
|
.access('type')
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
|
|
||||||
var ensureErrorHandler = require('error-inject');
|
var ensureErrorHandler = require('error-inject');
|
||||||
var getType = require('mime-types').contentType;
|
var getType = require('mime-types').contentType;
|
||||||
|
var onFinish = require('on-finished');
|
||||||
var isJSON = require('koa-is-json');
|
var isJSON = require('koa-is-json');
|
||||||
var escape = require('escape-html');
|
var escape = require('escape-html');
|
||||||
var onFinish = require('on-finished');
|
|
||||||
var typeis = require('type-is').is;
|
var typeis = require('type-is').is;
|
||||||
var status = require('statuses');
|
var statuses = require('statuses');
|
||||||
var destroy = require('destroy');
|
var destroy = require('destroy');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
|
@ -69,10 +69,33 @@ module.exports = {
|
||||||
|
|
||||||
set status(code) {
|
set status(code) {
|
||||||
assert('number' == typeof code, 'status code must be a number');
|
assert('number' == typeof code, 'status code must be a number');
|
||||||
assert(http.STATUS_CODES[code], 'invalid status code: ' + code);
|
assert(statuses[code], 'invalid status code: ' + code);
|
||||||
this._explicitStatus = true;
|
this._explicitStatus = true;
|
||||||
this.res.statusCode = code;
|
this.res.statusCode = code;
|
||||||
if (this.body && status.empty[code]) this.body = null;
|
this.res.statusMessage = statuses[code];
|
||||||
|
if (this.body && statuses.empty[code]) this.body = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get response status message
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
get message() {
|
||||||
|
return this.res.statusMessage || statuses[this.status];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set response status message
|
||||||
|
*
|
||||||
|
* @param {String} msg
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
set message(msg) {
|
||||||
|
this.res.statusMessage = msg;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,7 +122,7 @@ module.exports = {
|
||||||
|
|
||||||
// no content
|
// no content
|
||||||
if (null == val) {
|
if (null == val) {
|
||||||
if (!status.empty[this.status]) this.status = 204;
|
if (!statuses.empty[this.status]) this.status = 204;
|
||||||
this.res.removeHeader('Content-Type');
|
this.res.removeHeader('Content-Type');
|
||||||
this.res.removeHeader('Content-Length');
|
this.res.removeHeader('Content-Length');
|
||||||
this.res.removeHeader('Transfer-Encoding');
|
this.res.removeHeader('Transfer-Encoding');
|
||||||
|
@ -223,7 +246,7 @@ module.exports = {
|
||||||
this.set('Location', url);
|
this.set('Location', url);
|
||||||
|
|
||||||
// status
|
// status
|
||||||
if (!status.redirect[this.status]) this.status = 302;
|
if (!statuses.redirect[this.status]) this.status = 302;
|
||||||
|
|
||||||
// html
|
// html
|
||||||
if (this.ctx.accepts('html')) {
|
if (this.ctx.accepts('html')) {
|
||||||
|
@ -451,7 +474,7 @@ module.exports = {
|
||||||
toJSON: function(){
|
toJSON: function(){
|
||||||
return {
|
return {
|
||||||
status: this.status,
|
status: this.status,
|
||||||
string: http.STATUS_CODES[this.status],
|
message: this.message,
|
||||||
header: this.header
|
header: this.header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
var request = require('supertest');
|
var request = require('supertest');
|
||||||
|
var statuses = require('statuses');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
var koa = require('..');
|
var koa = require('..');
|
||||||
|
@ -487,6 +488,69 @@ describe('app.respond', function(){
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('with custom status=700', function(){
|
||||||
|
it('should respond with the associated status message', function (done){
|
||||||
|
var app = koa();
|
||||||
|
statuses['700'] = 'custom status';
|
||||||
|
|
||||||
|
app.use(function *(){
|
||||||
|
this.status = 700;
|
||||||
|
})
|
||||||
|
|
||||||
|
var server = app.listen();
|
||||||
|
|
||||||
|
request(server)
|
||||||
|
.get('/')
|
||||||
|
.expect(700)
|
||||||
|
.expect('custom status')
|
||||||
|
.end(function(err, res){
|
||||||
|
if (err) return done(err);
|
||||||
|
res.res.statusMessage.should.equal('custom status');
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('with custom statusMessage=ok', function(){
|
||||||
|
it('should respond with the custom status message', function (done){
|
||||||
|
var app = koa();
|
||||||
|
|
||||||
|
app.use(function *(){
|
||||||
|
this.status = 200;
|
||||||
|
this.message = 'ok';
|
||||||
|
})
|
||||||
|
|
||||||
|
var server = app.listen();
|
||||||
|
|
||||||
|
request(server)
|
||||||
|
.get('/')
|
||||||
|
.expect(200)
|
||||||
|
.expect('ok')
|
||||||
|
.end(function(err, res){
|
||||||
|
if (err) return done(err);
|
||||||
|
res.res.statusMessage.should.equal('ok');
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('with custom status without message', function (){
|
||||||
|
it('should respond with the status code number', function (done){
|
||||||
|
var app = koa();
|
||||||
|
|
||||||
|
app.use(function *(){
|
||||||
|
this.res.statusCode = 701;
|
||||||
|
})
|
||||||
|
|
||||||
|
var server = app.listen();
|
||||||
|
|
||||||
|
request(server)
|
||||||
|
.get('/')
|
||||||
|
.expect(701)
|
||||||
|
.expect('701', done);
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('when .body is a null', function(){
|
describe('when .body is a null', function(){
|
||||||
|
@ -909,12 +973,12 @@ describe('app.respond', function(){
|
||||||
|
|
||||||
describe('app.context', function(){
|
describe('app.context', function(){
|
||||||
var app1 = koa();
|
var app1 = koa();
|
||||||
app1.context.message = 'hello';
|
app1.context.msg = 'hello';
|
||||||
var app2 = koa();
|
var app2 = koa();
|
||||||
|
|
||||||
it('should merge properties', function(done){
|
it('should merge properties', function(done){
|
||||||
app1.use(function *(next){
|
app1.use(function *(next){
|
||||||
assert.equal(this.message, 'hello')
|
assert.equal(this.msg, 'hello')
|
||||||
this.status = 204
|
this.status = 204
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -925,7 +989,7 @@ describe('app.context', function(){
|
||||||
|
|
||||||
it('should not affect the original prototype', function(done){
|
it('should not affect the original prototype', function(done){
|
||||||
app2.use(function *(next){
|
app2.use(function *(next){
|
||||||
assert.equal(this.message, undefined)
|
assert.equal(this.msg, undefined)
|
||||||
this.status = 204;
|
this.status = 204;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -965,12 +1029,12 @@ describe('app.request', function(){
|
||||||
|
|
||||||
describe('app.response', function(){
|
describe('app.response', function(){
|
||||||
var app1 = koa();
|
var app1 = koa();
|
||||||
app1.response.message = 'hello';
|
app1.response.msg = 'hello';
|
||||||
var app2 = koa();
|
var app2 = koa();
|
||||||
|
|
||||||
it('should merge properties', function(done){
|
it('should merge properties', function(done){
|
||||||
app1.use(function *(next){
|
app1.use(function *(next){
|
||||||
assert.equal(this.response.message, 'hello')
|
assert.equal(this.response.msg, 'hello')
|
||||||
this.status = 204
|
this.status = 204
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -981,7 +1045,7 @@ describe('app.response', function(){
|
||||||
|
|
||||||
it('should not affect the original prototype', function(done){
|
it('should not affect the original prototype', function(done){
|
||||||
app2.use(function *(next){
|
app2.use(function *(next){
|
||||||
assert.equal(this.response.message, undefined)
|
assert.equal(this.response.msg, undefined)
|
||||||
this.status = 204;
|
this.status = 204;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ describe('ctx.toJSON()', function(){
|
||||||
|
|
||||||
res.should.eql({
|
res.should.eql({
|
||||||
status: 200,
|
status: 200,
|
||||||
string: 'OK',
|
message: 'OK',
|
||||||
header: {
|
header: {
|
||||||
'content-type': 'text/html; charset=utf-8',
|
'content-type': 'text/html; charset=utf-8',
|
||||||
'content-length': '10'
|
'content-length': '10'
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe('res.inspect()', function(){
|
||||||
res.inspect().should.eql({
|
res.inspect().should.eql({
|
||||||
body: 'hello',
|
body: 'hello',
|
||||||
status: 200,
|
status: 200,
|
||||||
string: 'OK',
|
message: 'OK',
|
||||||
header: {
|
header: {
|
||||||
'content-length': '5',
|
'content-length': '5',
|
||||||
'content-type': 'text/plain; charset=utf-8'
|
'content-type': 'text/plain; charset=utf-8'
|
||||||
|
|
29
test/response/message.js
Normal file
29
test/response/message.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
var Stream = require('stream');
|
||||||
|
var response = require('../context').response;
|
||||||
|
|
||||||
|
describe('res.message', function(){
|
||||||
|
it('should return the response status message', function(){
|
||||||
|
var res = response();
|
||||||
|
res.status = 200;
|
||||||
|
res.message.should.equal('OK');
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when res.message not present', function(){
|
||||||
|
it('should look up in statuses', function(){
|
||||||
|
var res = response();
|
||||||
|
res.res.statusCode = 200;
|
||||||
|
res.message.should.equal('OK');
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('res.message=', function(){
|
||||||
|
it('should set response status message', function(){
|
||||||
|
var res = response();
|
||||||
|
res.status = 200;
|
||||||
|
res.message = 'ok';
|
||||||
|
res.res.statusMessage.should.equal('ok');
|
||||||
|
res.inspect().message.should.equal('ok');
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
var response = require('../context').response;
|
var response = require('../context').response;
|
||||||
var request = require('supertest');
|
var request = require('supertest');
|
||||||
|
var statuses = require('statuses');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var koa = require('../..');
|
var koa = require('../..');
|
||||||
|
|
||||||
|
@ -27,6 +28,24 @@ describe('res.status=', function(){
|
||||||
}, 'invalid status code: 999');
|
}, 'invalid status code: 999');
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('and custom status', function (){
|
||||||
|
before(function () {
|
||||||
|
statuses['700'] = 'custom status';
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should set the status', function (){
|
||||||
|
var res = response();
|
||||||
|
res.status = 700;
|
||||||
|
res.status.should.equal(700);
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not throw', function(){
|
||||||
|
assert.doesNotThrow(function() {
|
||||||
|
response().status = 700;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('when a status string', function(){
|
describe('when a status string', function(){
|
||||||
|
|
Loading…
Reference in a new issue