Comparar commits
45 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 2787bd5bf0 | |||
| 6aaa7dc26d | |||
| ebf60d2340 | |||
| 02d43846f6 | |||
| 8930cd563c | |||
| 2b90cd7d51 | |||
| d5fde6a4b9 | |||
| 99b2e0fa08 | |||
| ebcb1ca90e | |||
| 1763b073f9 | |||
| 908e467548 | |||
| 3c6ad5350b | |||
| 0ff3aa4b20 | |||
| fd42b5c42c | |||
| 1311f2ac25 | |||
| 82a9817061 | |||
| 685eec0149 | |||
| 910dae16ab | |||
| fd53197b46 | |||
| d84d0b69ef | |||
| b694ba27be | |||
| e3cbac2d77 | |||
| bbaa295ee2 | |||
| 1150a88001 | |||
| 58cfd60000 | |||
| fcf268742d | |||
| 30d71c8f8f | |||
| c3f9398b12 | |||
| f1ac6ab764 | |||
| d6ca5f71bc | |||
| cdca9cf88f | |||
| 5840b42f4a | |||
| a5be68b5b2 | |||
| 9fda13bc25 | |||
| 125dd7a594 | |||
| df2584cc3b | |||
| 4de95c0e7b | |||
| 9ed1f2a446 | |||
| 833a4873a4 | |||
| 6ca1807372 | |||
| 9da3e9ccc7 | |||
| 5f65c36171 | |||
| d64bb2f886 | |||
| 8235af47fe | |||
| 908f3da3da |
@@ -1,4 +1,34 @@
|
||||
|
||||
3.0.0beta2 / 2012-06-06
|
||||
==================
|
||||
|
||||
* Added `+` support to the router
|
||||
* Added `req.host`
|
||||
* Changed `req.param()` to check route first
|
||||
* Update connect dep
|
||||
|
||||
3.0.0beta1 / 2012-06-01
|
||||
==================
|
||||
|
||||
* Added `res.format()` callback to override default 406 behaviour
|
||||
* Fixed `res.redirect()` 406. Closes #1154
|
||||
|
||||
3.0.0alpha5 / 2012-05-30
|
||||
==================
|
||||
|
||||
* Added `req.ip`
|
||||
* Added `{ signed: true }` option to `res.cookie()`
|
||||
* Removed `res.signedCookie()`
|
||||
* Changed: dont reverse `req.ips`
|
||||
* Fixed "trust proxy" setting check for `req.ips`
|
||||
|
||||
3.0.0alpha4 / 2012-05-09
|
||||
==================
|
||||
|
||||
* Added: allow `[]` in jsonp callback. Closes #1128
|
||||
* Added `PORT` env var support in generated template. Closes #1118 [benatkin]
|
||||
* Updated: connect 2.2.2
|
||||
|
||||
3.0.0alpha3 / 2012-05-04
|
||||
==================
|
||||
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ app.listen(3000);
|
||||
First install the dev dependencies to install all the example / test suite deps:
|
||||
|
||||
$ cd express
|
||||
$ npm install -d
|
||||
$ npm install
|
||||
|
||||
then run whichever tests you want:
|
||||
|
||||
|
||||
+7
-6
@@ -57,7 +57,7 @@ var index = [
|
||||
*/
|
||||
|
||||
var jadeLayout = [
|
||||
'!!!'
|
||||
'doctype 5'
|
||||
, 'html'
|
||||
, ' head'
|
||||
, ' title= title'
|
||||
@@ -181,13 +181,14 @@ var app = [
|
||||
, 'var app = express();'
|
||||
, ''
|
||||
, 'app.configure(function(){'
|
||||
, ' app.set(\'port\', process.env.PORT || 3000);'
|
||||
, ' app.set(\'views\', __dirname + \'/views\');'
|
||||
, ' app.set(\'view engine\', \':TEMPLATE\');'
|
||||
, ' app.use(express.favicon());'
|
||||
, ' app.use(express.logger(\'dev\'));{css}'
|
||||
, ' app.use(express.logger(\'dev\'));'
|
||||
, ' app.use(express.bodyParser());'
|
||||
, ' app.use(express.methodOverride());{sess}'
|
||||
, ' app.use(app.router);'
|
||||
, ' app.use(app.router);{css}'
|
||||
, ' app.use(express.static(__dirname + \'/public\'));'
|
||||
, '});'
|
||||
, ''
|
||||
@@ -197,9 +198,9 @@ var app = [
|
||||
, ''
|
||||
, 'app.get(\'/\', routes.index);'
|
||||
, ''
|
||||
, 'http.createServer(app).listen(3000);'
|
||||
, ''
|
||||
, 'console.log("Express server listening on port 3000");'
|
||||
, 'http.createServer(app).listen(app.get(\'port\'), function(){'
|
||||
, ' console.log("Express server listening on port " + app.get(\'port\'));'
|
||||
, '});'
|
||||
, ''
|
||||
].join(eol);
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
, app = module.exports = express();
|
||||
|
||||
// config
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'jade');
|
||||
|
||||
// middleware
|
||||
|
||||
app.configure('development',function(){
|
||||
app.use(express.logger('dev'));
|
||||
})
|
||||
|
||||
app.configure(function(){
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
app.use(express.cookieParser('keyboard cat'));
|
||||
app.use(express.session());
|
||||
app.use(app.router);
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
|
||||
});
|
||||
|
||||
// Locals
|
||||
|
||||
app.locals.use(function(req, res){
|
||||
// expose "error" and "message" to all
|
||||
// views that are rendered.
|
||||
res.locals.error = req.session.error || '';
|
||||
res.locals.message = req.session.message || '';
|
||||
// remove them so they're not displayed on subsequent renders
|
||||
delete req.session.error;
|
||||
delete req.session.message;
|
||||
});
|
||||
|
||||
// Routes
|
||||
|
||||
require('./routes/site')(app);
|
||||
require('./routes/post')(app);
|
||||
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
// Fake data store
|
||||
|
||||
var ids = 0
|
||||
, db = {};
|
||||
|
||||
var Post = exports = module.exports = function Post(title, body) {
|
||||
this.id = ++ids;
|
||||
this.title = title;
|
||||
this.body = body;
|
||||
this.createdAt = new Date;
|
||||
};
|
||||
|
||||
Post.prototype.save = function(fn){
|
||||
db[this.id] = this;
|
||||
fn();
|
||||
};
|
||||
|
||||
Post.prototype.validate = function(fn){
|
||||
if (!this.title) return fn(new Error('title required'));
|
||||
if (!this.body) return fn(new Error('body required'));
|
||||
if (this.body.length < 10) {
|
||||
return fn(new Error(
|
||||
'body should be at least 10 characters long, was only ' + this.body.length));
|
||||
}
|
||||
fn();
|
||||
};
|
||||
|
||||
|
||||
Post.prototype.update = function(data, fn){
|
||||
this.updatedAt = new Date;
|
||||
for (var key in data) {
|
||||
if (undefined != data[key]) {
|
||||
this[key] = data[key];
|
||||
}
|
||||
}
|
||||
this.save(fn);
|
||||
};
|
||||
|
||||
Post.prototype.destroy = function(fn){
|
||||
exports.destroy(this.id, fn);
|
||||
};
|
||||
|
||||
exports.count = function(fn){
|
||||
fn(null, Object.keys(db).length);
|
||||
};
|
||||
|
||||
exports.all = function(fn){
|
||||
var arr = Object.keys(db).reduce(function(arr, id){
|
||||
arr.push(db[id]);
|
||||
return arr;
|
||||
}, []);
|
||||
fn(null, arr);
|
||||
};
|
||||
|
||||
exports.get = function(id, fn){
|
||||
fn(null, db[id]);
|
||||
};
|
||||
|
||||
exports.destroy = function(id, fn) {
|
||||
if (db[id]) {
|
||||
delete db[id];
|
||||
fn();
|
||||
} else {
|
||||
fn(new Error('post ' + id + ' does not exist'));
|
||||
}
|
||||
};
|
||||
@@ -1,56 +0,0 @@
|
||||
body {
|
||||
font: 13px "Helvetica Neue", Arial, sans-serif;
|
||||
color: #111;
|
||||
padding: 60px 80px;
|
||||
}
|
||||
h1, h2 {
|
||||
color: #c00;
|
||||
}
|
||||
a {
|
||||
color: #c00;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
label {
|
||||
padding: 6px 0;
|
||||
display: block;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
textarea,
|
||||
input {
|
||||
outline: none;
|
||||
padding: 5px;
|
||||
background: #f1f1f1;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
textarea:focus,
|
||||
input:focus {
|
||||
background: #fff;
|
||||
}
|
||||
textarea {
|
||||
width: 500px;
|
||||
height: 200px;
|
||||
}
|
||||
a.edit {
|
||||
margin-left: 10px;
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.date {
|
||||
font-size: 11px;
|
||||
}
|
||||
p.error,
|
||||
p.message {
|
||||
padding: 10px;
|
||||
border: 1px solid;
|
||||
}
|
||||
p.error {
|
||||
background: #FDEAE7;
|
||||
color: #E4250C;
|
||||
}
|
||||
p.message {
|
||||
color: #2EBBE6;
|
||||
background: #F7FBFD;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var basicAuth = require('../../../lib/express').basicAuth
|
||||
, Post = require('../models/post');
|
||||
|
||||
module.exports = function(app){
|
||||
/**
|
||||
* Apply basic auth to all post related routes
|
||||
*/
|
||||
|
||||
app.all('/post(/*)?', basicAuth(function(user, pass){
|
||||
return 'admin' == user && 'express' == pass;
|
||||
}));
|
||||
|
||||
/**
|
||||
* Map :post to the database, loading
|
||||
* every time :post is present.
|
||||
*/
|
||||
|
||||
app.param('post', function(req, res, next, id){
|
||||
Post.get(id, function(err, post){
|
||||
if (err) return next(err);
|
||||
if (!post) return next(new Error('failed to load post ' + id));
|
||||
req.post = post;
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Add a post.
|
||||
*/
|
||||
|
||||
app.get('/post/add', function(req, res){
|
||||
res.render('post/form', { post: {}});
|
||||
});
|
||||
|
||||
/**
|
||||
* Save a post.
|
||||
*/
|
||||
|
||||
app.post('/post', function(req, res){
|
||||
var data = req.body.post || {}
|
||||
, post = new Post(data.title, data.body);
|
||||
|
||||
post.validate(function(err){
|
||||
if (err) {
|
||||
req.session.error = err.message;
|
||||
return res.redirect('back');
|
||||
}
|
||||
|
||||
post.save(function(err){
|
||||
req.session.message = 'Successfully created the post.';
|
||||
res.redirect('/post/' + post.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Display the post.
|
||||
*/
|
||||
|
||||
app.get('/post/:post', function(req, res){
|
||||
res.render('post', { post: req.post });
|
||||
});
|
||||
|
||||
/**
|
||||
* Display the post edit form.
|
||||
*/
|
||||
|
||||
app.get('/post/:post/edit', function(req, res){
|
||||
res.render('post/form', { post: req.post });
|
||||
});
|
||||
|
||||
/**
|
||||
* Update post. Typically a data layer would handle this stuff.
|
||||
*/
|
||||
|
||||
app.put('/post/:post', function(req, res, next){
|
||||
var post = req.post;
|
||||
post.validate(function(err){
|
||||
if (err) {
|
||||
req.session.error = err.message;
|
||||
return res.redirect('back');
|
||||
}
|
||||
|
||||
post.update(req.body.post, function(err){
|
||||
if (err) return next(err);
|
||||
req.session.message = 'Successfully updated post';
|
||||
res.redirect('back');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Post = require('../models/post');
|
||||
|
||||
module.exports = function(app){
|
||||
app.get('/', function(req, res){
|
||||
Post.count(function(err, count){
|
||||
Post.all(function(err, posts){
|
||||
res.render('index', {
|
||||
count: count
|
||||
, posts: posts
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
extends layout
|
||||
|
||||
block content
|
||||
h1 Blog
|
||||
|
||||
if count
|
||||
p Display all #{count} post(s)
|
||||
#posts
|
||||
each post in posts
|
||||
include post/index
|
||||
else
|
||||
p
|
||||
| It looks like you have no posts!
|
||||
p
|
||||
| Click
|
||||
a(href='/post/add') here
|
||||
| to create a post. Login
|
||||
| as
|
||||
em "admin"
|
||||
| and
|
||||
em "express"
|
||||
| .
|
||||
@@ -1,8 +0,0 @@
|
||||
!!! 5
|
||||
html
|
||||
head
|
||||
title Blog
|
||||
link(rel='stylesheet', href='/style.css')
|
||||
body
|
||||
#container
|
||||
block content
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
if error
|
||||
p.error= error
|
||||
|
||||
if message
|
||||
p.message= message
|
||||
@@ -1,22 +0,0 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
if post.title
|
||||
h1 Editing #{post.title}
|
||||
else
|
||||
h1 New Post
|
||||
|
||||
include ../messages
|
||||
|
||||
form#post(action='/post' + (post.title ? '/' + post.id : ''), method='post')
|
||||
if post.title
|
||||
input(type='hidden', name='_method', value='put')
|
||||
p
|
||||
label(for='post[title]') Title:
|
||||
input(type='text', name='post[title]', value=post.title)
|
||||
p
|
||||
label(for='post[body]') Body:
|
||||
textarea(name='post[body]')= post.body || ''
|
||||
p
|
||||
input(type='submit', value=post.title ? 'Update' : 'Create')
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
extends ../layout
|
||||
|
||||
block content
|
||||
.post
|
||||
// title
|
||||
h2
|
||||
= post.title
|
||||
a.edit(href='/post/' + post.id + '/edit') Edit
|
||||
|
||||
include ../messages
|
||||
|
||||
// dates
|
||||
p.date.created Created at #{post.createdAt}
|
||||
if post.updatedAt
|
||||
p.date.updated Updated at #{post.updatedAt}
|
||||
|
||||
// body
|
||||
pre.body= post.body
|
||||
+1
-1
@@ -22,7 +22,7 @@ exports = module.exports = createApplication;
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
exports.version = '3.0.0alpha3';
|
||||
exports.version = '3.0.0beta2';
|
||||
|
||||
/**
|
||||
* Create an express application.
|
||||
|
||||
+35
-28
@@ -208,8 +208,8 @@ req.__defineGetter__('acceptedCharsets', function(){
|
||||
/**
|
||||
* Return the value of param `name` when present or `defaultValue`.
|
||||
*
|
||||
* - Checks body params, ex: id=12, {"id":12}
|
||||
* - Checks route placeholders, ex: _/user/:id_
|
||||
* - Checks body params, ex: id=12, {"id":12}
|
||||
* - Checks query string params, ex: ?id=12
|
||||
*
|
||||
* To utilize request bodies, `req.body`
|
||||
@@ -223,19 +223,12 @@ req.__defineGetter__('acceptedCharsets', function(){
|
||||
*/
|
||||
|
||||
req.param = function(name, defaultValue){
|
||||
// req.body
|
||||
if (this.body && undefined !== this.body[name]) return this.body[name];
|
||||
|
||||
// route params
|
||||
if (this.params
|
||||
&& this.params.hasOwnProperty(name)
|
||||
&& undefined !== this.params[name]) {
|
||||
return this.params[name];
|
||||
}
|
||||
|
||||
// query-string
|
||||
if (undefined !== this.query[name]) return this.query[name];
|
||||
|
||||
var params = this.params || {};
|
||||
var body = this.body || {};
|
||||
var query = this.query || {};
|
||||
if (null != params[name] && params.hasOwnProperty(name)) return params[name];
|
||||
if (null != body[name]) return body[name];
|
||||
if (null != query[name]) return query[name];
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
@@ -260,17 +253,6 @@ req.param = function(name, defaultValue){
|
||||
* req.is('html');
|
||||
* // => false
|
||||
*
|
||||
* Now within our route callbacks, we can use to to assert content types
|
||||
* such as "image/jpeg", "image/png" as shown here:
|
||||
*
|
||||
* app.post('/image/upload', function(req, res, next){
|
||||
* if (req.is('image/*')) {
|
||||
* // do something
|
||||
* } else {
|
||||
* next();
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
@@ -325,12 +307,25 @@ req.__defineGetter__('secure', function(){
|
||||
return 'https' == this.protocol;
|
||||
});
|
||||
|
||||
/**
|
||||
* Return the remote address, or when
|
||||
* "trust proxy" is `true` return
|
||||
* the upstream addr.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('ip', function(){
|
||||
return this.ips[0] || this.connection.remoteAddress;
|
||||
});
|
||||
|
||||
/**
|
||||
* When "trust proxy" is `true`, parse
|
||||
* the "X-Forwarded-For" ip address list.
|
||||
*
|
||||
* For example if the value were "client, proxy1, proxy2"
|
||||
* you would receive the array `["proxy2", "proxy1", "client"]`
|
||||
* you would receive the array `["client", "proxy1", "proxy2"]`
|
||||
* where "proxy2" is the furthest down-stream.
|
||||
*
|
||||
* @return {Array}
|
||||
@@ -338,9 +333,10 @@ req.__defineGetter__('secure', function(){
|
||||
*/
|
||||
|
||||
req.__defineGetter__('ips', function(){
|
||||
var trustProxy = this.app.get('trust proxy');
|
||||
var val = this.get('X-Forwarded-For');
|
||||
return val
|
||||
? val.split(/ *, */).reverse()
|
||||
return trustProxy && val
|
||||
? val.split(/ *, */)
|
||||
: [];
|
||||
});
|
||||
|
||||
@@ -372,6 +368,17 @@ req.__defineGetter__('path', function(){
|
||||
return parse(this).pathname;
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse the "Host" header field hostname.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('host', function(){
|
||||
return this.get('Host').split(':')[0];
|
||||
});
|
||||
|
||||
/**
|
||||
* Check if the request is fresh, aka
|
||||
* Last-Modified and/or the ETag
|
||||
|
||||
+25
-24
@@ -12,6 +12,7 @@ var fs = require('fs')
|
||||
, normalizeTypes = require('./utils').normalizeTypes
|
||||
, statusCodes = http.STATUS_CODES
|
||||
, send = connect.static.send
|
||||
, cookie = require('cookie')
|
||||
, crc = require('crc')
|
||||
, mime = require('mime')
|
||||
, basename = path.basename
|
||||
@@ -159,7 +160,7 @@ res.json = function(obj){
|
||||
|
||||
if (callback && jsonp) {
|
||||
this.set('Content-Type', 'text/javascript');
|
||||
body = callback.replace(/[^\w$.]/g, '') + '(' + body + ');';
|
||||
body = callback.replace(/[^[]\w$.]/g, '') + '(' + body + ');';
|
||||
}
|
||||
|
||||
return this.send(body);
|
||||
@@ -251,7 +252,7 @@ res.sendfile = function(path, options, fn){
|
||||
* when the data transfer is complete, or when an error has
|
||||
* ocurred. Be sure to check `res.headerSent` if you plan to respond.
|
||||
*
|
||||
* This method uses `res.attachment()` and `res.sendfile()`.
|
||||
* This method uses `res.sendfile()`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {String|Function} filename or fn
|
||||
@@ -266,7 +267,9 @@ res.download = function(path, filename, fn){
|
||||
filename = null;
|
||||
}
|
||||
|
||||
return this.attachment(filename || path).sendfile(path, fn);
|
||||
filename = filename || path;
|
||||
this.set('Content-Disposition', 'attachment; filename="' + basename(filename) + '"');
|
||||
return this.sendfile(path, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -339,12 +342,19 @@ res.type = function(type){
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* By default Express passes an `Error`
|
||||
* with a `.status` of 406 to `next(err)`
|
||||
* if a match is not made, however you may
|
||||
* provide an optional callback `fn` to
|
||||
* be invoked instead.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {Function} fn
|
||||
* @return {ServerResponse} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.format = function(obj){
|
||||
res.format = function(obj, fn){
|
||||
var keys = Object.keys(obj)
|
||||
, req = this.req
|
||||
, next = req.next
|
||||
@@ -355,6 +365,8 @@ res.format = function(obj){
|
||||
if (key) {
|
||||
this.set('Content-Type', normalizeType(key));
|
||||
obj[key](req, this, next);
|
||||
} else if (fn) {
|
||||
fn();
|
||||
} else {
|
||||
var err = new Error('Not Acceptable');
|
||||
err.status = 406;
|
||||
@@ -438,30 +450,13 @@ res.clearCookie = function(name, options){
|
||||
: opts);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a signed cookie with the given `name` and `val`.
|
||||
* See `res.cookie()` for details.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String|Object} val
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.signedCookie = function(name, val, options){
|
||||
var secret = this.req.secret;
|
||||
if (!secret) throw new Error('connect.cookieParser("secret") required for signed cookies');
|
||||
if ('object' == typeof val) val = 'j:' + JSON.stringify(val);
|
||||
val = utils.sign(val, secret);
|
||||
return this.cookie(name, val, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set cookie `name` to `val`, with the given `options`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxAge` max-age in milliseconds, converted to `expires`
|
||||
* - `signed` sign the cookie
|
||||
* - `path` defaults to "/"
|
||||
*
|
||||
* Examples:
|
||||
@@ -480,11 +475,14 @@ res.signedCookie = function(name, val, options){
|
||||
|
||||
res.cookie = function(name, val, options){
|
||||
options = options || {};
|
||||
var secret = this.req.secret;
|
||||
var signed = options.signed;
|
||||
if (signed && !secret) throw new Error('connect.cookieParser("secret") required for signed cookies');
|
||||
if ('object' == typeof val) val = 'j:' + JSON.stringify(val);
|
||||
if (signed) val = utils.sign(val, secret);
|
||||
if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);
|
||||
if (null == options.path) options.path = '/';
|
||||
var cookie = utils.serializeCookie(name, val, options);
|
||||
this.set('Set-Cookie', cookie);
|
||||
this.set('Set-Cookie', cookie.serialize(name, String(val), options));
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -566,11 +564,14 @@ res.redirect = function(url){
|
||||
html: function(){
|
||||
body = '<p>' + statusCodes[status] + '. Redirecting to <a href="' + url + '">' + url + '</a></p>';
|
||||
}
|
||||
}, function(){
|
||||
body = '';
|
||||
})
|
||||
|
||||
// Respond
|
||||
this.statusCode = status;
|
||||
this.set('Location', url);
|
||||
this.set('Content-Length', Buffer.byteLength(body));
|
||||
this.end(head ? null : body);
|
||||
};
|
||||
|
||||
|
||||
@@ -264,6 +264,7 @@ exports.pathRegexp = function(path, keys, sensitive, strict) {
|
||||
path = path
|
||||
.concat(strict ? '' : '/?')
|
||||
.replace(/\/\(/g, '(?:/')
|
||||
.replace(/\+/g, '__plus__')
|
||||
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){
|
||||
keys.push({ name: key, optional: !! optional });
|
||||
slash = slash || '';
|
||||
@@ -275,6 +276,7 @@ exports.pathRegexp = function(path, keys, sensitive, strict) {
|
||||
+ (optional || '');
|
||||
})
|
||||
.replace(/([\/.])/g, '\\$1')
|
||||
.replace(/__plus__/g, '(.+)')
|
||||
.replace(/\*/g, '(.*)');
|
||||
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
|
||||
}
|
||||
+2
-2
@@ -1,14 +1,14 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var path = require('path')
|
||||
, fs = require('fs')
|
||||
, utils = require('./utils')
|
||||
, dirname = path.dirname
|
||||
, basename = path.basename
|
||||
, extname = path.extname
|
||||
, exists = path.existsSync
|
||||
, exists = fs.existsSync || path.existsSync
|
||||
, join = path.join;
|
||||
|
||||
/**
|
||||
|
||||
+5
-4
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "3.0.0alpha3",
|
||||
"version": "3.0.0beta2",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
|
||||
@@ -10,10 +10,11 @@
|
||||
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
|
||||
],
|
||||
"dependencies": {
|
||||
"connect": "2.2.1",
|
||||
"commander": "0.5.2",
|
||||
"connect": "2.3.1",
|
||||
"commander": "0.6.1",
|
||||
"mime": "1.2.5",
|
||||
"mkdirp": "0.3.1",
|
||||
"mkdirp": "0.3.2",
|
||||
"cookie": "0.0.3",
|
||||
"crc": "0.2.0",
|
||||
"debug": "*"
|
||||
},
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
|
||||
var app = require('../../examples/blog')
|
||||
, request = require('../support/http');
|
||||
|
||||
var authorization = 'Basic ' + Buffer('admin:express').toString('base64');
|
||||
|
||||
function redirects(to,fn){
|
||||
return function(res){
|
||||
res.statusCode.should.equal(302)
|
||||
res.headers.should.have.property('location').match(to);
|
||||
fn()
|
||||
}
|
||||
}
|
||||
|
||||
describe('blog', function(){
|
||||
describe('GET /', function(){
|
||||
it('should have no posts', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(/you have no posts/, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /post/add', function(){
|
||||
it('should require auth', function(done){
|
||||
request(app)
|
||||
.get('/post/add')
|
||||
.expect(401, done)
|
||||
})
|
||||
|
||||
it('should login', function(done){
|
||||
request(app)
|
||||
.get('/post/add')
|
||||
.set('Authorization', authorization)
|
||||
.expect(/<h1>New Post<\/h1>/, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /post', function(){
|
||||
it('should require auth', function(done){
|
||||
request(app)
|
||||
.post('/post')
|
||||
.expect(401, done)
|
||||
})
|
||||
|
||||
it('should redirect to / with no title or body', function(done){
|
||||
request(app)
|
||||
.post('/post')
|
||||
.set('Authorization', authorization)
|
||||
.end(redirects(/\/$/, done))
|
||||
})
|
||||
|
||||
it('should redirect to / with no body', function(done){
|
||||
request(app)
|
||||
.post('/post')
|
||||
.set('Authorization', authorization)
|
||||
.set('Content-Type', 'application/x-www-form-urlencoded')
|
||||
.write('post[title]=Kittens')
|
||||
.end(redirects(/\/$/, done))
|
||||
})
|
||||
|
||||
it('should redirect to /post/:post when successful', function(done){
|
||||
request(app)
|
||||
.post('/post')
|
||||
.set('Authorization', authorization)
|
||||
.set('Content-Type', 'application/x-www-form-urlencoded')
|
||||
.write('post[title]=Kittens&post[body]=In+very+large+baskets')
|
||||
.end(redirects(/\/post\/\d+$/, done))
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /', function(){
|
||||
it('should now list 1 post',function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(/Display all 1 post/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
+41
-18
@@ -256,23 +256,6 @@ describe('app.router', function(){
|
||||
})
|
||||
})
|
||||
|
||||
it('should allow escaped regexp', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/user/\\d+', function(req, res){
|
||||
res.end('woot');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/user/10')
|
||||
.end(function(res){
|
||||
res.statusCode.should.equal(200);
|
||||
request(app)
|
||||
.get('/user/tj')
|
||||
.expect(404, done);
|
||||
});
|
||||
})
|
||||
|
||||
it('should allow literal "."', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -288,10 +271,32 @@ describe('app.router', function(){
|
||||
.expect('users from 1 to 50', done);
|
||||
})
|
||||
|
||||
describe('*', function(){
|
||||
describe('+', function(){
|
||||
it('should denote a greedy capture group', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/blog+', function(req, res){
|
||||
res.end(req.params[0] || 'nothing');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/blog')
|
||||
.expect(404, function(){
|
||||
request(app)
|
||||
.get('/blog/post')
|
||||
.expect(200, function(){
|
||||
request(app)
|
||||
.get('/blog-admin')
|
||||
.expect(200, done)
|
||||
})
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('*', function(){
|
||||
it('should denote an optional greedy capture group', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/user/*.json', function(req, res){
|
||||
res.end(req.params[0]);
|
||||
});
|
||||
@@ -551,4 +556,22 @@ describe('app.router', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('should allow rewriting of the url', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/account/edit', function(req, res, next){
|
||||
req.user = { id: 12 }; // faux authenticated user
|
||||
req.url = '/user/' + req.user.id + '/edit';
|
||||
next();
|
||||
});
|
||||
|
||||
app.get('/user/:id/edit', function(req, res){
|
||||
res.send('editing user ' + req.params.id);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/account/edit')
|
||||
.expect('editing user 12', done);
|
||||
})
|
||||
})
|
||||
|
||||
+3
-1
@@ -1,6 +1,7 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
, request = require('./support/http')
|
||||
, assert = require('assert');
|
||||
|
||||
describe('req', function(){
|
||||
describe('.get(field)', function(){
|
||||
@@ -8,6 +9,7 @@ describe('req', function(){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
assert(req.get('Something-Else') === undefined);
|
||||
res.end(req.get('Content-Type'));
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
var express = require('../');
|
||||
|
||||
function req(ret) {
|
||||
return {
|
||||
get: function(){ return ret }
|
||||
, __proto__: express.request
|
||||
};
|
||||
}
|
||||
|
||||
describe('req', function(){
|
||||
describe('.host', function(){
|
||||
it('should return hostname', function(){
|
||||
req('example.com:3000').host.should.equal('example.com');
|
||||
req('example.com').host.should.equal('example.com');
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
|
||||
describe('req', function(){
|
||||
describe('.ip', function(){
|
||||
describe('when X-Forwarded-For is present', function(){
|
||||
describe('when "trust proxy" is enabled', function(){
|
||||
it('should return the client addr', function(done){
|
||||
var app = express();
|
||||
|
||||
app.enable('trust proxy');
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.send(req.ip);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('X-Forwarded-For', 'client, p1, p2')
|
||||
.expect('client', done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when "trust proxy" is disabled', function(){
|
||||
it('should return the remote address', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.send(req.ip);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('X-Forwarded-For', 'client, p1, p2')
|
||||
.expect('127.0.0.1', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when X-Forwarded-For is not present', function(){
|
||||
it('should return the remote address', function(done){
|
||||
var app = express();
|
||||
|
||||
app.enable('trust proxy');
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.send(req.ip);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('127.0.0.1', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
+28
-9
@@ -5,17 +5,36 @@ var express = require('../')
|
||||
describe('req', function(){
|
||||
describe('.ips', function(){
|
||||
describe('when X-Forwarded-For is present', function(){
|
||||
it('should return an array of the specified addresses', function(done){
|
||||
var app = express();
|
||||
describe('when "trust proxy" is enabled', function(){
|
||||
it('should return an array of the specified addresses', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.send(req.ips);
|
||||
});
|
||||
app.enable('trust proxy');
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('X-Forwarded-For', 'client, p1, p2')
|
||||
.expect('["p2","p1","client"]', done);
|
||||
app.use(function(req, res, next){
|
||||
res.send(req.ips);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('X-Forwarded-For', 'client, p1, p2')
|
||||
.expect('["client","p1","p2"]', done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when "trust proxy" is disabled', function(){
|
||||
it('should return an empty array', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.send(req.ips);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('X-Forwarded-For', 'client, p1, p2')
|
||||
.expect('[]', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
+2
-2
@@ -59,13 +59,13 @@ describe('req', function(){
|
||||
var app = express();
|
||||
|
||||
app.get('/user/:name', function(req, res){
|
||||
res.end(req.param('name'));
|
||||
res.end(req.param('filter') + req.param('name'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/user/tj')
|
||||
.end(function(res){
|
||||
res.body.should.equal('tj');
|
||||
res.body.should.equal('undefinedtj');
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
@@ -14,7 +14,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = 'sid=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
var val = 'sid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
res.headers['set-cookie'].should.eql([val]);
|
||||
done();
|
||||
})
|
||||
@@ -32,7 +32,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = 'sid=; path=/admin; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
var val = 'sid=; Path=/admin; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
res.headers['set-cookie'].should.eql([val]);
|
||||
done();
|
||||
})
|
||||
|
||||
+47
-5
@@ -1,6 +1,7 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
, request = require('./support/http')
|
||||
, cookie = require('cookie');
|
||||
|
||||
describe('res', function(){
|
||||
describe('.cookie(name, object)', function(){
|
||||
@@ -14,7 +15,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = ['user=j%3A%7B%22name%22%3A%22tobi%22%7D; path=/'];
|
||||
var val = ['user=j:{%22name%22:%22tobi%22}; Path=/'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
@@ -32,7 +33,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = ['name=tobi; path=/'];
|
||||
var val = ['name=tobi; Path=/'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
@@ -50,7 +51,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = ['name=tobi; path=/', 'age=1; path=/'];
|
||||
var val = ['name=tobi; Path=/', 'age=1; Path=/'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
@@ -69,7 +70,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = ['name=tobi; path=/; httpOnly; secure'];
|
||||
var val = ['name=tobi; Path=/; HttpOnly; Secure'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
@@ -92,5 +93,46 @@ describe('res', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('signed', function(){
|
||||
it('should generate a signed JSON cookie', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.cookieParser('foo bar baz'));
|
||||
|
||||
app.use(function(req, res){
|
||||
res.cookie('user', { name: 'tobi' }, { signed: true }).end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = res.headers['set-cookie'][0];
|
||||
val = cookie.parse(val.split('.')[0]);
|
||||
val.user.should.equal('j:{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.signedCookie(name, string)', function(){
|
||||
it('should set a signed cookie', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.cookieParser('foo bar baz'));
|
||||
|
||||
app.use(function(req, res){
|
||||
res.cookie('name', 'tobi', { signed: true }).end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = ['name=tobi.xJjV2iZ6EI7C8E5kzwbfA9PVLl1ZR07UTnuTgQQ4EnQ; Path=/'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http')
|
||||
, assert = require('assert');
|
||||
|
||||
describe('res', function(){
|
||||
describe('.download(path)', function(){
|
||||
it('should transfer as an attachment', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.download('test/fixtures/user.html');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
|
||||
res.should.have.header('Content-Disposition', 'attachment; filename="user.html"');
|
||||
res.body.should.equal('<p>{{user.name}}</p>');
|
||||
done();
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('.download(path, filename)', function(){
|
||||
it('should provide an alternate filename', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.download('test/fixtures/user.html', 'document');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
|
||||
res.should.have.header('Content-Disposition', 'attachment; filename="document"');
|
||||
done();
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('.download(path, fn)', function(){
|
||||
it('should invoke the callback', function(done){
|
||||
var app = express()
|
||||
, calls = 0;
|
||||
|
||||
app.use(function(req, res){
|
||||
res.download('test/fixtures/user.html', done);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
|
||||
res.should.have.header('Content-Disposition', 'attachment; filename="user.html"');
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('.download(path, filename, fn)', function(){
|
||||
it('should invoke the callback', function(done){
|
||||
var app = express()
|
||||
, calls = 0;
|
||||
|
||||
app.use(function(req, res){
|
||||
res.download('test/fixtures/user.html', 'document', done);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
|
||||
res.should.have.header('Content-Disposition', 'attachment; filename="document"');
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
+6
-15
@@ -1,23 +1,14 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
, res = express.response;
|
||||
|
||||
describe('res', function(){
|
||||
describe('.get(field)', function(){
|
||||
it('should get the response header field', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.setHeader('Content-Type', 'text/x-foo');
|
||||
res.end(res.get('Content-Type'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
res.body.should.equal('text/x-foo');
|
||||
done();
|
||||
})
|
||||
it('should get the response header field', function(){
|
||||
res.setHeader('Content-Type', 'text/x-foo');
|
||||
res.get('Content-Type').should.equal('text/x-foo');
|
||||
res.get('Content-type').should.equal('text/x-foo');
|
||||
res.get('content-type').should.equal('text/x-foo');
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+16
-1
@@ -9,7 +9,6 @@ describe('res', function(){
|
||||
it('should respond with jsonp', function(done){
|
||||
var app = express();
|
||||
|
||||
// app.enable('jsonp callback');
|
||||
app.use(function(req, res){
|
||||
res.json({ count: 1 });
|
||||
});
|
||||
@@ -22,6 +21,22 @@ describe('res', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should allow []', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.json({ count: 1 });
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/?callback=callbacks[123]')
|
||||
.end(function(res){
|
||||
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
|
||||
res.body.should.equal('callbacks[123]({"count":1});');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when given primitives', function(){
|
||||
|
||||
@@ -248,9 +248,32 @@ describe('res', function(){
|
||||
.set('Accept', 'text/plain, */*')
|
||||
.end(function(res){
|
||||
res.headers.should.have.property('location', 'http://google.com');
|
||||
res.headers.should.have.property('content-length', '51');
|
||||
res.body.should.equal('Moved Temporarily. Redirecting to http://google.com');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when accepting neither text or html', function(){
|
||||
it('should respond with an empty body', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.redirect('http://google.com');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'foo/bar')
|
||||
.end(function(res){
|
||||
res.should.have.status(302);
|
||||
res.headers.should.have.property('location', 'http://google.com');
|
||||
res.headers.should.not.have.property('content-type');
|
||||
res.headers.should.have.property('content-length', '0');
|
||||
res.body.should.equal('');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+16
-1
@@ -24,7 +24,22 @@ describe('res', function(){
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
it('should utilize the same options as express.static()', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.sendfile('test/fixtures/user.html', { maxAge: 60000 });
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
res.should.have.header('Cache-Control', 'public, max-age=60');
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('should invoke the callback on 404', function(done){
|
||||
var app = express()
|
||||
, calls = 0;
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
|
||||
describe('res', function(){
|
||||
describe('.signedCookie(name, object)', function(){
|
||||
it('should generate a signed JSON cookie', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.cookieParser('foo bar baz'));
|
||||
|
||||
app.use(function(req, res){
|
||||
res.signedCookie('user', { name: 'tobi' }).end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = res.headers['set-cookie'][0];
|
||||
val = decodeURIComponent(val.split('.')[0]);
|
||||
val.should.equal('user=j:{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.signedCookie(name, string)', function(){
|
||||
it('should set a signed cookie', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(express.cookieParser('foo bar baz'));
|
||||
|
||||
app.use(function(req, res){
|
||||
res.signedCookie('name', 'tobi').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(res){
|
||||
var val = ['name=tobi.xJjV2iZ6EI7C8E5kzwbfA9PVLl1ZR07UTnuTgQQ4EnQ; path=/'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
Referência em uma Nova Issue
Bloquear um usuário