diff options
| author | Teddy Wing | 2013-04-27 19:25:40 -0400 | 
|---|---|---|
| committer | Teddy Wing | 2013-04-27 19:25:56 -0400 | 
| commit | 512e8b2da71de59132a29e80d7359ac843d62f07 (patch) | |
| tree | 3f5024a4f75072eda45713dcd429a0b58bf969b9 /node_modules/express/lib/response.js | |
| parent | 4b14305623d5ddc59f435fc5e35c54c0def1d392 (diff) | |
| download | Who-am-I-512e8b2da71de59132a29e80d7359ac843d62f07.tar.bz2 | |
Untrack ./node_modules
Sorry, my bad for not ignoring it initially.
Diffstat (limited to 'node_modules/express/lib/response.js')
| -rw-r--r-- | node_modules/express/lib/response.js | 756 | 
1 files changed, 0 insertions, 756 deletions
| diff --git a/node_modules/express/lib/response.js b/node_modules/express/lib/response.js deleted file mode 100644 index 50fcd05..0000000 --- a/node_modules/express/lib/response.js +++ /dev/null @@ -1,756 +0,0 @@ -/** - * Module dependencies. - */ - -var http = require('http') -  , path = require('path') -  , connect = require('connect') -  , utils = connect.utils -  , sign = require('cookie-signature').sign -  , normalizeType = require('./utils').normalizeType -  , normalizeTypes = require('./utils').normalizeTypes -  , etag = require('./utils').etag -  , statusCodes = http.STATUS_CODES -  , cookie = require('cookie') -  , send = require('send') -  , mime = connect.mime -  , basename = path.basename -  , extname = path.extname -  , join = path.join; - -/** - * Response prototype. - */ - -var res = module.exports = { -  __proto__: http.ServerResponse.prototype -}; - -/** - * Set status `code`. - * - * @param {Number} code - * @return {ServerResponse} - * @api public - */ - -res.status = function(code){ -  this.statusCode = code; -  return this; -}; - -/** - * Set Link header field with the given `links`. - * - * Examples: - * - *    res.links({ - *      next: 'http://api.example.com/users?page=2', - *      last: 'http://api.example.com/users?page=5' - *    }); - * - * @param {Object} links - * @return {ServerResponse} - * @api public - */ - -res.links = function(links){ -  return this.set('Link', Object.keys(links).map(function(rel){ -    return '<' + links[rel] + '>; rel="' + rel + '"'; -  }).join(', ')); -}; - -/** - * Send a response. - * - * Examples: - * - *     res.send(new Buffer('wahoo')); - *     res.send({ some: 'json' }); - *     res.send('<p>some html</p>'); - *     res.send(404, 'Sorry, cant find that'); - *     res.send(404); - * - * @param {Mixed} body or status - * @param {Mixed} body - * @return {ServerResponse} - * @api public - */ - -res.send = function(body){ -  var req = this.req -    , head = 'HEAD' == req.method -    , len; - -  // allow status / body -  if (2 == arguments.length) { -    // res.send(body, status) backwards compat -    if ('number' != typeof body && 'number' == typeof arguments[1]) { -      this.statusCode = arguments[1]; -    } else { -      this.statusCode = body; -      body = arguments[1]; -    } -  } - -  switch (typeof body) { -    // response status -    case 'number': -      this.get('Content-Type') || this.type('txt'); -      this.statusCode = body; -      body = http.STATUS_CODES[body]; -      break; -    // string defaulting to html -    case 'string': -      if (!this.get('Content-Type')) { -        this.charset = this.charset || 'utf-8'; -        this.type('html'); -      } -      break; -    case 'boolean': -    case 'object': -      if (null == body) { -        body = ''; -      } else if (Buffer.isBuffer(body)) { -        this.get('Content-Type') || this.type('bin'); -      } else { -        return this.json(body); -      } -      break; -  } - -  // populate Content-Length -  if (undefined !== body && !this.get('Content-Length')) { -    this.set('Content-Length', len = Buffer.isBuffer(body) -      ? body.length -      : Buffer.byteLength(body)); -  } - -  // ETag support -  // TODO: W/ support -  if (len > 1024) { -    if (!this.get('ETag')) { -      this.set('ETag', etag(body)); -    } -  } - -  // freshness -  if (req.fresh) this.statusCode = 304; - -  // strip irrelevant headers -  if (204 == this.statusCode || 304 == this.statusCode) { -    this.removeHeader('Content-Type'); -    this.removeHeader('Content-Length'); -    this.removeHeader('Transfer-Encoding'); -    body = ''; -  } - -  // respond -  this.end(head ? null : body); -  return this; -}; - -/** - * Send JSON response. - * - * Examples: - * - *     res.json(null); - *     res.json({ user: 'tj' }); - *     res.json(500, 'oh noes!'); - *     res.json(404, 'I dont have that'); - * - * @param {Mixed} obj or status - * @param {Mixed} obj - * @return {ServerResponse} - * @api public - */ - -res.json = function(obj){ -  // allow status / body -  if (2 == arguments.length) { -    // res.json(body, status) backwards compat -    if ('number' == typeof arguments[1]) { -      this.statusCode = arguments[1]; -    } else { -      this.statusCode = obj; -      obj = arguments[1]; -    } -  } - -  // settings -  var app = this.app; -  var replacer = app.get('json replacer'); -  var spaces = app.get('json spaces'); -  var body = JSON.stringify(obj, replacer, spaces); - -  // content-type -  this.charset = this.charset || 'utf-8'; -  this.get('Content-Type') || this.set('Content-Type', 'application/json'); - -  return this.send(body); -}; - -/** - * Send JSON response with JSONP callback support. - * - * Examples: - * - *     res.jsonp(null); - *     res.jsonp({ user: 'tj' }); - *     res.jsonp(500, 'oh noes!'); - *     res.jsonp(404, 'I dont have that'); - * - * @param {Mixed} obj or status - * @param {Mixed} obj - * @return {ServerResponse} - * @api public - */ - -res.jsonp = function(obj){ -  // allow status / body -  if (2 == arguments.length) { -    // res.json(body, status) backwards compat -    if ('number' == typeof arguments[1]) { -      this.statusCode = arguments[1]; -    } else { -      this.statusCode = obj; -      obj = arguments[1]; -    } -  } - -  // settings -  var app = this.app; -  var replacer = app.get('json replacer'); -  var spaces = app.get('json spaces'); -  var body = JSON.stringify(obj, replacer, spaces) -    .replace(/\u2028/g, '\\u2028') -    .replace(/\u2029/g, '\\u2029'); -  var callback = this.req.query[app.get('jsonp callback name')]; - -  // content-type -  this.charset = this.charset || 'utf-8'; -  this.set('Content-Type', 'application/json'); - -  // jsonp -  if (callback) { -    this.set('Content-Type', 'text/javascript'); -    var cb = callback.replace(/[^\[\]\w$.]/g, ''); -    body = cb + ' && ' + cb + '(' + body + ');'; -  } - -  return this.send(body); -}; - -/** - * Transfer the file at the given `path`. - * - * Automatically sets the _Content-Type_ response header field. - * The callback `fn(err)` is invoked when the transfer is complete - * or when an error occurs. Be sure to check `res.sentHeader` - * if you wish to attempt responding, as the header and some data - * may have already been transferred. - * - * Options: - * - *   - `maxAge` defaulting to 0 - *   - `root`   root directory for relative filenames - * - * Examples: - * - *  The following example illustrates how `res.sendfile()` may - *  be used as an alternative for the `static()` middleware for - *  dynamic situations. The code backing `res.sendfile()` is actually - *  the same code, so HTTP cache support etc is identical. - * - *     app.get('/user/:uid/photos/:file', function(req, res){ - *       var uid = req.params.uid - *         , file = req.params.file; - * - *       req.user.mayViewFilesFrom(uid, function(yes){ - *         if (yes) { - *           res.sendfile('/uploads/' + uid + '/' + file); - *         } else { - *           res.send(403, 'Sorry! you cant see that.'); - *         } - *       }); - *     }); - * - * @param {String} path - * @param {Object|Function} options or fn - * @param {Function} fn - * @api public - */ - -res.sendfile = function(path, options, fn){ -  var self = this -    , req = self.req -    , next = this.req.next -    , options = options || {} -    , done; - -  // support function as second arg -  if ('function' == typeof options) { -    fn = options; -    options = {}; -  } - -  // socket errors -  req.socket.on('error', error); - -  // errors -  function error(err) { -    if (done) return; -    done = true; - -    // clean up -    cleanup(); -    if (!self.headerSent) self.removeHeader('Content-Disposition'); - -    // callback available -    if (fn) return fn(err); - -    // list in limbo if there's no callback -    if (self.headerSent) return; - -    // delegate -    next(err); -  } - -  // streaming -  function stream() { -    if (done) return; -    cleanup(); -    if (fn) self.on('finish', fn); -  } - -  // cleanup -  function cleanup() { -    req.socket.removeListener('error', error); -  } - -  // transfer -  var file = send(req, path); -  if (options.root) file.root(options.root); -  file.maxage(options.maxAge || 0); -  file.on('error', error); -  file.on('directory', next); -  file.on('stream', stream); -  file.pipe(this); -  this.on('finish', cleanup); -}; - -/** - * Transfer the file at the given `path` as an attachment. - * - * Optionally providing an alternate attachment `filename`, - * and optional callback `fn(err)`. The callback is invoked - * 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.sendfile()`. - * - * @param {String} path - * @param {String|Function} filename or fn - * @param {Function} fn - * @api public - */ - -res.download = function(path, filename, fn){ -  // support function as second arg -  if ('function' == typeof filename) { -    fn = filename; -    filename = null; -  } - -  filename = filename || path; -  this.set('Content-Disposition', 'attachment; filename="' + basename(filename) + '"'); -  return this.sendfile(path, fn); -}; - -/** - * Set _Content-Type_ response header with `type` through `mime.lookup()` - * when it does not contain "/", or set the Content-Type to `type` otherwise. - * - * Examples: - * - *     res.type('.html'); - *     res.type('html'); - *     res.type('json'); - *     res.type('application/json'); - *     res.type('png'); - * - * @param {String} type - * @return {ServerResponse} for chaining - * @api public - */ - -res.contentType = -res.type = function(type){ -  return this.set('Content-Type', ~type.indexOf('/') -    ? type -    : mime.lookup(type)); -}; - -/** - * Respond to the Acceptable formats using an `obj` - * of mime-type callbacks. - * - * This method uses `req.accepted`, an array of - * acceptable types ordered by their quality values. - * When "Accept" is not present the _first_ callback - * is invoked, otherwise the first match is used. When - * no match is performed the server responds with - * 406 "Not Acceptable". - * - * Content-Type is set for you, however if you choose - * you may alter this within the callback using `res.type()` - * or `res.set('Content-Type', ...)`. - * - *    res.format({ - *      'text/plain': function(){ - *        res.send('hey'); - *      }, - * - *      'text/html': function(){ - *        res.send('<p>hey</p>'); - *      }, - * - *      'appliation/json': function(){ - *        res.send({ message: 'hey' }); - *      } - *    }); - * - * In addition to canonicalized MIME types you may - * also use extnames mapped to these types: - * - *    res.format({ - *      text: function(){ - *        res.send('hey'); - *      }, - * - *      html: function(){ - *        res.send('<p>hey</p>'); - *      }, - * - *      json: function(){ - *        res.send({ message: 'hey' }); - *      } - *    }); - * - * By default Express passes an `Error` - * with a `.status` of 406 to `next(err)` - * if a match is not made. If you provide - * a `.default` callback it will be invoked - * instead. - * - * @param {Object} obj - * @return {ServerResponse} for chaining - * @api public - */ - -res.format = function(obj){ -  var req = this.req -    , next = req.next; - -  var fn = obj.default; -  if (fn) delete obj.default; -  var keys = Object.keys(obj); - -  var key = req.accepts(keys); - -  this.set('Vary', 'Accept'); - -  if (key) { -    this.set('Content-Type', normalizeType(key).value); -    obj[key](req, this, next); -  } else if (fn) { -    fn(); -  } else { -    var err = new Error('Not Acceptable'); -    err.status = 406; -    err.types = normalizeTypes(keys).map(function(o){ return o.value }); -    next(err); -  } - -  return this; -}; - -/** - * Set _Content-Disposition_ header to _attachment_ with optional `filename`. - * - * @param {String} filename - * @return {ServerResponse} - * @api public - */ - -res.attachment = function(filename){ -  if (filename) this.type(extname(filename)); -  this.set('Content-Disposition', filename -    ? 'attachment; filename="' + basename(filename) + '"' -    : 'attachment'); -  return this; -}; - -/** - * Set header `field` to `val`, or pass - * an object of header fields. - * - * Examples: - * - *    res.set('Foo', ['bar', 'baz']); - *    res.set('Accept', 'application/json'); - *    res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' }); - * - * Aliased as `res.header()`. - * - * @param {String|Object|Array} field - * @param {String} val - * @return {ServerResponse} for chaining - * @api public - */ - -res.set = -res.header = function(field, val){ -  if (2 == arguments.length) { -    if (Array.isArray(val)) val = val.map(String); -    else val = String(val); -    this.setHeader(field, val); -  } else { -    for (var key in field) { -      this.set(key, field[key]); -    } -  } -  return this; -}; - -/** - * Get value for header `field`. - * - * @param {String} field - * @return {String} - * @api public - */ - -res.get = function(field){ -  return this.getHeader(field); -}; - -/** - * Clear cookie `name`. - * - * @param {String} name - * @param {Object} options - * @param {ServerResponse} for chaining - * @api public - */ - -res.clearCookie = function(name, options){ -  var opts = { expires: new Date(1), path: '/' }; -  return this.cookie(name, '', options -    ? utils.merge(opts, options) -    : opts); -}; - -/** - * 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: - * - *    // "Remember Me" for 15 minutes - *    res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true }); - * - *    // save as above - *    res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true }) - * - * @param {String} name - * @param {String|Object} val - * @param {Options} options - * @api public - */ - -res.cookie = function(name, val, options){ -  options = utils.merge({}, 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 = 's:' + sign(val, secret); -  if ('maxAge' in options) { -    options.expires = new Date(Date.now() + options.maxAge); -    options.maxAge /= 1000; -  } -  if (null == options.path) options.path = '/'; -  this.set('Set-Cookie', cookie.serialize(name, String(val), options)); -  return this; -}; - - -/** - * Set the location header to `url`. - * - * The given `url` can also be the name of a mapped url, for - * example by default express supports "back" which redirects - * to the _Referrer_ or _Referer_ headers or "/". - * - * Examples: - * - *    res.location('/foo/bar').; - *    res.location('http://example.com'); - *    res.location('../login'); // /blog/post/1 -> /blog/login - * - * Mounting: - * - *   When an application is mounted and `res.location()` - *   is given a path that does _not_ lead with "/" it becomes - *   relative to the mount-point. For example if the application - *   is mounted at "/blog", the following would become "/blog/login". - * - *      res.location('login'); - * - *   While the leading slash would result in a location of "/login": - * - *      res.location('/login'); - * - * @param {String} url - * @api public - */ - -res.location = function(url){ -  var app = this.app -    , req = this.req; - -  // setup redirect map -  var map = { back: req.get('Referrer') || '/' }; - -  // perform redirect -  url = map[url] || url; - -  // relative -  if (!~url.indexOf('://') && 0 != url.indexOf('//')) { -    var path - -    // relative to path -    if ('.' == url[0]) { -      path = req.originalUrl.split('?')[0] -      url =  path + ('/' == path[path.length - 1] ? '' : '/') + url; -      // relative to mount-point -    } else if ('/' != url[0]) { -      path = app.path(); -      url = path + '/' + url; -    } -  } - -  // Respond -  this.set('Location', url); -  return this; -}; - -/** - * Redirect to the given `url` with optional response `status` - * defaulting to 302. - * - * The resulting `url` is determined by `res.location()`, so - * it will play nicely with mounted apps, relative paths, - * `"back"` etc. - * - * Examples: - * - *    res.redirect('/foo/bar'); - *    res.redirect('http://example.com'); - *    res.redirect(301, 'http://example.com'); - *    res.redirect('http://example.com', 301); - *    res.redirect('../login'); // /blog/post/1 -> /blog/login - * - * @param {String} url - * @param {Number} code - * @api public - */ - -res.redirect = function(url){ -  var app = this.app -    , head = 'HEAD' == this.req.method -    , status = 302 -    , body; - -  // allow status / url -  if (2 == arguments.length) { -    if ('number' == typeof url) { -      status = url; -      url = arguments[1]; -    } else { -      status = arguments[1]; -    } -  } - -  // Set location header -  this.location(url); -  url = this.get('Location'); - -  // Support text/{plain,html} by default -  this.format({ -    text: function(){ -      body = statusCodes[status] + '. Redirecting to ' + encodeURI(url); -    }, - -    html: function(){ -      var u = utils.escape(url); -      body = '<p>' + statusCodes[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>'; -    }, - -    default: function(){ -      body = ''; -    } -  }); - -  // Respond -  this.statusCode = status; -  this.set('Content-Length', Buffer.byteLength(body)); -  this.end(head ? null : body); -}; - -/** - * Render `view` with the given `options` and optional callback `fn`. - * When a callback function is given a response will _not_ be made - * automatically, otherwise a response of _200_ and _text/html_ is given. - * - * Options: - * - *  - `cache`     boolean hinting to the engine it should cache - *  - `filename`  filename of the view being rendered - * - * @param  {String} view - * @param  {Object|Function} options or callback function - * @param  {Function} fn - * @api public - */ - -res.render = function(view, options, fn){ -  var self = this -    , options = options || {} -    , req = this.req -    , app = req.app; - -  // support callback function as second arg -  if ('function' == typeof options) { -    fn = options, options = {}; -  } - -  // merge res.locals -  options._locals = self.locals; - -  // default callback to respond -  fn = fn || function(err, str){ -    if (err) return req.next(err); -    self.send(str); -  }; - -  // render -  app.render(view, options, fn); -}; | 
