Comparar commits

...

45 Commits

Autor SHA1 Mensagem Data
visionmedia db2eb658ca Release 0.13.0 2010-06-01 08:49:04 -07:00
visionmedia 70483484ce Fixed upload example 2010-06-01 08:44:26 -07:00
visionmedia d21afc43a1 Merge branch 'charset' of git://github.com/aheckmann/express 2010-05-31 14:06:29 -07:00
visionmedia 7ad0803f2e Updated package.json 2010-05-31 14:05:15 -07:00
Aaron Heckmann ec4bfd55f9 not-found exceptions using utf-8 2010-05-31 12:58:53 -04:00
Aaron Heckmann f65174a0db show-exceptions uses utf-8 2010-05-31 12:56:30 -04:00
visionmedia 8b1fcd4dd7 mime.type() no longer accepts ".type" 2010-05-30 13:14:08 -07:00
visionmedia 9509237958 Fixed mime.type() due to path.extname() changes 2010-05-30 13:04:35 -07:00
visionmedia f20fd20a06 Fixed view support due to fs.readFile Buffers 2010-05-30 12:46:15 -07:00
visionmedia 8e48120fb7 Updated JSpec 2010-05-30 12:42:31 -07:00
visionmedia 44cc5ac883 Updated haml submodule 2010-05-27 15:32:30 -07:00
visionmedia 9a43cc8c4b Updated haml submodule 2010-05-25 16:08:50 -07:00
visionmedia 8dfc0d54f4 Updated haml submodule 2010-05-25 13:49:30 -07:00
visionmedia 77febd21de Fixed code styling 2010-05-23 09:38:42 -07:00
Aaron Heckmann 84a997c66b Added support for deleting cookies via Request#cookie('key', null) 2010-05-23 09:37:53 -07:00
Aaron Heckmann b900a59fc2 respond(204) should not have a body 2010-05-22 12:13:15 -04:00
visionmedia ca782dbc58 Release 0.12.0 2010-05-22 08:24:22 -07:00
visionmedia 746cda27ec Fixed cookie spec urlencoding 2010-05-22 08:23:28 -07:00
visionmedia 16d1651656 Fixed a cookie spec 2010-05-22 08:22:01 -07:00
visionmedia 4735fb2377 Merge branch 'master' of git://github.com/tritonrc/express 2010-05-22 08:21:08 -07:00
Aaron Heckmann ec6b518fd2 compatible with node v0.1.96 2010-05-22 08:09:09 -07:00
Brian McKinney 580ad1b192 Make sure to URL encode cookie name and value on response if we are going to URL decode on request 2010-05-18 18:53:01 -06:00
visionmedia 23d8810486 Updated haml submodule 2010-05-17 15:43:38 -07:00
visionmedia d579d62eb6 Comment changed to match others 2010-05-14 07:30:14 -07:00
visionmedia 529f785e3c Merge branch 'master' of git://github.com/Guille/express 2010-05-14 07:28:53 -07:00
Guillermo Rauch 0581ae87b4 Renaming Globals to helpers (I'm sold) 2010-05-14 11:16:51 -03:00
visionmedia cda1059336 Updated readme, we are compatible with node --version v0.1.95 2010-05-14 06:51:59 -07:00
Aaron Heckmann 1aed6b5c30 Merge branch 'master' into encoding 2010-05-14 08:05:46 -04:00
Aaron Heckmann 4e68705b24 compatible with node v0.1.95 2010-05-14 08:01:05 -04:00
Guillermo Rauch 216cb1ea12 Added support for globals (eg: helpers) in views
- Added export.Globals in plugins/view.js
 - Added two specs (one for a simple template, one for a template with a layout) with a dummy i18n helper
 - Updated README features list
2010-05-13 20:35:25 -03:00
Guillermo Rauch 8ef6a0b432 Merge branch 'master' of http://github.com/visionmedia/express
* 'master' of http://github.com/visionmedia/express: (168 commits)
  Updated haml submodule
  s/==/===/
  Misc refactoring to make parseCookie() more readable / spec for overriding keys
  s/QueryString/queryString/
  Added spec for malformed cookies
  regexps have no "n" flag
  No need to quote key in spec
  Fixed LF -> CRLF for setting multiple cookies
  Redo cookies parsing to accept quoted values and url escaped cookies
  Remove inode from ETag, modified time only
  Release 0.11.0
  Works fine with node --version v0.1.94
  Refactoring some spec fixtures
  Fixing spec for EJS partial
  Updated ext
  Updated haml
  Added spec / refactored layout of different engine support
  Added spec for layouts with different engines
  Fixing EJS partial support by passing along the context. Issue #307
  Allow layouts to use different engines
  ...

Conflicts:
	lib/express/core.js
2010-05-13 18:53:11 -03:00
visionmedia 5dc152c46e Updated haml submodule 2010-05-11 13:22:32 -07:00
visionmedia c3a21437e4 Merge branch 'integration' 2010-05-11 07:57:50 -07:00
visionmedia 32bc8dcbf9 s/==/===/ 2010-05-11 07:57:24 -07:00
visionmedia 677ca7b4aa Misc refactoring to make parseCookie() more readable / spec for overriding keys 2010-05-11 07:55:15 -07:00
visionmedia dfc2331104 s/QueryString/queryString/ 2010-05-11 07:47:20 -07:00
visionmedia cd06bbfb8d Added spec for malformed cookies 2010-05-11 07:46:44 -07:00
visionmedia 1d596bcbac regexps have no "n" flag 2010-05-11 07:44:31 -07:00
visionmedia 0cb7b9c13d No need to quote key in spec 2010-05-11 07:42:23 -07:00
visionmedia a180efeca7 Merge branch 'master' of git://github.com/tritonrc/express into integration 2010-05-11 07:41:15 -07:00
visionmedia eef24ea29c Fixed LF -> CRLF for setting multiple cookies 2010-05-11 07:25:08 -07:00
Brian McKinney 458bb3d7f7 Redo cookies parsing to accept quoted values and url escaped cookies 2010-05-10 17:18:42 -06:00
visionmedia ffb23d92c0 Remove inode from ETag, modified time only 2010-05-07 13:52:13 -07:00
Guillermo Rauch b0884ad7c3 Correction 2010-03-25 19:33:45 -07:00
Guillermo Rauch cf09f86df2 Expose the http.Server instance 2010-03-25 19:17:43 -07:00
23 arquivos alterados com 159 adições e 59 exclusões
+22
Ver Arquivo
@@ -1,4 +1,26 @@
0.13.0 / 2010-06-01
==================
* Added node v0.1.97 compatibility
* Added support for deleting cookies via Request#cookie('key', null)
* Updated haml submodule
* Fixed not-found page, now using using charset utf-8
* Fixed show-exceptions page, now using using charset utf-8
* Fixed view support due to fs.readFile Buffers
* Changed; mime.type() no longer accepts ".type" due to node extname() changes
0.12.0 / 2010-05-22
==================
* Added node v0.1.96 compatibility
* Added view `helpers` export which act as additional local variables
* Updated haml submodule
* Changed ETag; removed inode, modified time only
* Fixed LF to CRLF for setting multiple cookies
* Fixed cookie complation; values are now urlencoded
* Fixed cookies parsing; accepts quoted values and url escaped cookies
0.11.0 / 2010-05-06
==================
+2 -1
Ver Arquivo
@@ -25,6 +25,7 @@
* Route passing
* View support (ejs, haml, sass, etc)
* View partials
* View globals/helpers support
* Full test coverage
* Logger plugin with several formats
* Upload size restrictions
@@ -86,7 +87,7 @@ Run individual suites:
...
The latest release of Express is compatible with node --version:
v0.1.94
v0.1.97
With _EDGE_ Express we do our best to keep up to date with node's _EDGE_
+1 -2
Ver Arquivo
@@ -2,7 +2,6 @@
.images
- each img in images
%img{ src: img }
%h2 Singles
%form{ method: 'post', enctype: 'multipart/form-data' }
%input{ type: 'file', name: 'images[0]' }
@@ -10,7 +9,7 @@
%input{ type: 'file', name: 'images[2]' }
%div.panel
%input{ type: 'submit', value: 'Upload' }
%h2 Multiple
%form{ method: 'post', enctype: 'multipart/form-data' }
%input{ type: 'file', name: 'images[]', multiple: 'multiple' }
+2 -2
Ver Arquivo
@@ -209,7 +209,7 @@ Server = new Class({
var server = http
.createServer(function(req, response){
var request, pendingFiles = 0
req.setBodyEncoding('binary')
req.setEncoding('binary')
request = new Request(req, response)
request.body = ''
function callback(err) {
@@ -291,7 +291,7 @@ Server = new Class({
// --- Express
Express = {
version: '0.11.0',
version: '0.13.0',
config: [],
routes: [],
plugins: [],
-1
Ver Arquivo
@@ -352,7 +352,6 @@ exports.types = {
*
* var mime = require('express/mime')
* mime.type('png') // => 'image/png'
* mime.type('.png') // => 'image/png'
* mime.type('image.png') // => 'image/png'
* mime.type('path/to/image.png') // => 'image/png'
*
+1
Ver Arquivo
@@ -4,6 +4,7 @@
var style = require('express/pages/style').style
exports.render = function(request) {
request.charset = 'UTF-8'
request.contentType('html')
var method = request.method.toLowerCase(),
path = request.url.pathname || '/'
+1
Ver Arquivo
@@ -79,6 +79,7 @@ function hashText(hash) {
}
exports.render = function(request, e) {
request.charset = 'UTF-8'
request.contentType('html')
return '<html> \n\
<head> \n\
+26 -13
Ver Arquivo
@@ -5,7 +5,8 @@
* Module dependencies.
*/
var Request = require('express/request').Request
var Request = require('express/request').Request,
queryString = require('querystring')
/**
* Parse an HTTP _cookie_ string into a hash.
@@ -16,10 +17,18 @@ var Request = require('express/request').Request
*/
exports.parseCookie = function(cookie) {
return cookie.replace(/^ *| *$/g, '').split(/ *; */).reduce(function(hash, pair){
var parts = pair.split(/ *= */)
hash[parts[0]] = parts[1]
return hash
return cookie.split(/[;,] */).reduce(function(cookies, pair) {
var eql = pair.indexOf('=')
if (eql === -1) return cookies
var key = queryString.unescape(pair.slice(0, eql).trim(), true)
var val = queryString.unescape(pair.slice(eql + 1).trim(), true)
var captures = val.match(/^("|')([^\1]*)\1$/)
if (captures) val = captures[2].replace('\\' + captures[1], captures[1])
//RFC2109 states the most specific path will be
//listed first
if (cookies[key] === undefined)
cookies[key] = val
return cookies
}, {})
}
@@ -36,7 +45,7 @@ exports.parseCookie = function(cookie) {
exports.compileCookie = function(name, val, options) {
if (!options) return name + '=' + val
var val,
buf = [name + '=' + val],
buf = [queryString.escape(name) + '=' + queryString.escape(val)],
keys = Object.keys(options)
for (var i = 0, len = keys.length; i < len; ++i) {
val = options[keys[i]]
@@ -62,7 +71,8 @@ exports.Cookie = Plugin.extend({
Request.include({
/**
* Get or set cookie values.
* Get or set cookie values. To delete a cookie
* simply pass a null _val_.
*
* Options:
*
@@ -85,10 +95,13 @@ exports.Cookie = Plugin.extend({
cookie: function(name, val, options) {
options = options || {}
options.path = options.path || '/'
return val ?
this.response.cookies.push(exports.compileCookie(name, val, options)) :
this.cookies[name]
}
if (null === val)
val = "delete",
options.expires = new Date(10000000)
return val
? this.response.cookies.push(exports.compileCookie(name, val, options))
: this.cookies[name]
}
})
}
},
@@ -115,7 +128,7 @@ exports.Cookie = Plugin.extend({
response: function(event) {
if (event.response.cookies &&
event.response.cookies.length)
event.request.header('Set-Cookie', event.response.cookies.join('\nSet-Cookie: '))
event.request.header('Set-Cookie', event.response.cookies.join('\r\nSet-Cookie: '))
}
}
})
})
+1 -1
Ver Arquivo
@@ -62,7 +62,7 @@ exports.Static = Plugin.extend({
return 'errno' in err && err.errno === 2
? self.notFound()
: self.error(err, callback)
var etag = stat.ino + '-' + stat.size + '-' + Number(stat.mtime)
var etag = Number(stat.mtime)
if (self.header('If-None-Match') &&
self.header('If-None-Match') == etag)
return self.respond(304, null)
+13 -5
Ver Arquivo
@@ -19,7 +19,14 @@ var engines = {}
* View cache.
*/
var cache = { views: {}, partials: {}}
var cache = { views: {}, partials: {} }
/**
* View helpers (merged with locals).
*/
var helpers = exports.helpers = {}
/**
* Cache view files where _type_ is
@@ -35,7 +42,7 @@ function cacheFiles(type) {
fs.readdirSync(dir).each(function(file){
file = dir + '/' + file
if (!fs.statSync(file).isFile()) return
cache[type][file] = fs.readFileSync(file)
cache[type][file] = fs.readFileSync(file).toString('utf8')
})
} catch (e) {
if (e.errno !== process.ENOENT) throw e
@@ -153,10 +160,12 @@ exports.View = Plugin.extend({
layout = options.layout === undefined
? 'layout'
: options.layout
options.locals = options.locals || {}
Object.merge(options.locals, helpers)
options.filename = path
if (set('cache view contents'))
options.cache = true
var content = cache[type][path] || fs.readFileSync(path)
var content = cache[type][path] || fs.readFileSync(path).toString(options.encoding || 'utf8')
options.context = options.context || this
content = (engines[engine] = engines[engine] || require(engine)).render(content, options)
if (type === 'views') this.contentType(contentType)
@@ -178,5 +187,4 @@ exports.View = Plugin.extend({
})
}
}
})
})
+3 -1
Ver Arquivo
@@ -193,7 +193,9 @@ exports.Request = new Class({
if (encoding instanceof Function)
callback = encoding,
encoding = null
if (body !== null)
if (204 === code)
body = null
else if (body !== null)
body = body || statusBodies[code]
if (encoding === 'utf8' ||
encoding === 'utf-8')
+3 -3
Ver Arquivo
@@ -1,14 +1,14 @@
{
"name": "Express",
"description": "Sinatra inspired web development framework",
"version": "0.11.0",
"version": "0.13.0",
"keywords": ["framework", "sinatra", "web", "rest", "restful"],
"directories": {
"lib": "lib"
"lib": "./lib"
},
"scripts": {
"install": "git submodule update --init",
"test": "make test"
},
"engines": { "node": ">= 0.1.93" }
"engines": { "node": ">= 0.1.97" }
}
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
---
name: Express
description: Sinatra inspired web development framework
version: 0.11.0
version: 0.12.0
+1
Ver Arquivo
@@ -0,0 +1 @@
Testing
+1
Ver Arquivo
@@ -0,0 +1 @@
%span= _('Hello world')
+1
Ver Arquivo
@@ -0,0 +1 @@
%span= _(body)
+17 -13
Ver Arquivo
@@ -4,7 +4,7 @@
;(function(){
JSpec = {
version : '4.2.1',
version : '4.3.2',
assert : true,
cache : {},
suites : [],
@@ -1749,10 +1749,14 @@
// --- Node.js support
if (typeof GLOBAL === 'object' && typeof exports === 'object')
quit = process.exit,
print = require('sys').puts,
readFile = require('fs').readFileSync
if (typeof GLOBAL === 'object' && typeof exports === 'object') {
var fs = require('fs')
quit = process.exit
print = require('sys').puts
readFile = function(file){
return fs.readFileSync(file).toString('utf8')
}
}
// --- Utility functions
@@ -1872,17 +1876,17 @@
},
have_prop : function(actual, property, value) {
return actual[property] === undefined ||
actual[property] instanceof Function ? false:
value === undefined ? true:
does(actual[property], 'eql', value)
var actualVal = actual[property], actualType = typeof actualVal
return (actualType == 'function' || actualType == 'undefined') ? false :
typeof value === 'undefined' ||
does(actual[property],'eql',value)
},
have_property : function(actual, property, value) {
return actual[property] === undefined ||
actual[property] instanceof Function ? false:
value === undefined ? true:
value === actual[property]
var actualVal = actual[property], actualType = typeof actualVal
return (actualType == 'function' || actualType == 'undefined') ? false :
typeof value === 'undefined' ||
value === actualVal
}
})
+3 -1
Ver Arquivo
@@ -34,7 +34,9 @@
*/
getAllResponseHeaders : function(){
return this.responseHeaders
return JSpec.inject(this.responseHeaders, '', function(buf, key, val){
return buf + key + ': ' + val + '\r\n'
})
},
/**
-4
Ver Arquivo
@@ -4,10 +4,6 @@ require("jspec")
require("express")
require("express/spec")
print = require('sys').puts
quit = process.exit
readFile = require('fs').readFileSync
function run(specs) {
specs.forEach(function(spec){
JSpec.exec('spec/spec.' + spec + '.js')
-6
Ver Arquivo
@@ -10,12 +10,6 @@ describe 'Express'
describe 'mime'
describe 'type()'
describe 'when given an extension with leading dot'
it 'should return the associated mime type'
mime.type('.png').should.eql 'image/png'
end
end
describe 'when given an extension without leading dot'
it 'should return the associated mime type'
mime.type('png').should.eql 'image/png'
+36 -3
Ver Arquivo
@@ -55,6 +55,21 @@ describe 'Express'
var attrs = ' SID = 1232431234234 ; data = foo'
parseCookie(attrs).should.eql { SID: '1232431234234', data: 'foo' }
end
it 'should support complex quoted values'
var attrs = 'SID="123456789"; fbs_0011223355="uid=0987654321&name=Test+User"'
parseCookie(attrs).should.eql { SID: '123456789', fbs_0011223355: 'uid=0987654321&name=Test User' }
end
it 'should not override when a duplicate key is found'
var attrs = 'SID=1234; SID=9999'
parseCookie(attrs).should.eql { SID: '1234' }
end
it 'should support malformed cookies'
var attrs = 'SID'
parseCookie(attrs).should.eql {}
end
end
describe 'on'
@@ -82,7 +97,25 @@ describe 'Express'
this.cookie('foo', 'bar')
return ''
})
get('/user').headers['Set-Cookie'].should.eql 'SID=732423sdfs73243; path=/; secure\nSet-Cookie: foo=bar; path=/'
get('/user').headers['Set-Cookie'].should.eql 'SID=732423sdfs73243; path=/; secure\r\nSet-Cookie: foo=bar; path=/'
end
it 'should delete the cookie'
get('/user', function(){
this.cookie('ninja', null)
this.cookie('pirate', null)
return ''
})
get('/user').headers['Set-Cookie'].should.eql 'ninja=delete; path=/; expires=Thu, 01 Jan 1970 02:46:40 GMT\r\nSet-Cookie: pirate=delete; path=/; expires=Thu, 01 Jan 1970 02:46:40 GMT'
end
it 'should support URL unfriendly characters'
get('/user', function(){
this.cookie('spaceship', '<*==*>', { path: '/', secure: true })
this.cookie(':)', 'smileyface')
return ''
})
get('/user').headers['Set-Cookie'].should.eql 'spaceship=%3C*%3D%3D*%3E; path=/; secure\r\nSet-Cookie: %3A)=smileyface; path=/'
end
end
end
@@ -92,9 +125,9 @@ describe 'Express'
get('/user', function(){
return this.cookie('foo')
})
get('/user', { headers: { cookie: 'foo=bar' }}).body.should.eql 'bar'
get('/user', { headers: { cookie: 'foo=bar%3D%3D' }}).body.should.eql 'bar=='
end
end
end
end
end
+23 -1
Ver Arquivo
@@ -1,5 +1,6 @@
ejs = require('ejs')
helpers = require('express/plugins/view').helpers
describe 'Express'
before_each
@@ -178,7 +179,7 @@ describe 'Express'
get('/', function(){
this.render('hello.html.haml', { layout: 'front' })
})
-{ get('/') }.should.throw_error 'ENOENT, No such file or directory'
-{ get('/') }.should.throw_error "ENOENT, No such file or directory 'spec/fixtures/front.html.haml'"
end
end
@@ -213,6 +214,27 @@ describe 'Express'
end
end
describe 'when a global is set'
it 'should include the helper and translate the text in the view'
helpers._ = function(text){
if (text == 'Hello world') return 'Hola mundo'
}
get('/', function(){
this.render('helpers.html.haml', { layout: false })
})
get('/').body.should.include 'Hola mundo'
end
it 'should include the helper and translate the text in the layout'
helpers._ = function(text){
if (text == 'Testing') return 'Probando'
}
get('/', function(){
this.render('helpers-layout.html.haml', { layout: 'layout-helper' })
})
get('/').body.should.include 'Probando'
end
end
describe 'when engine cannot be found'
it 'should throw an error'
get('/', function(){