|
- /*
- * response-stream.js: A Stream focused on writing any relevant information to
- * a raw http.ServerResponse object.
- *
- * (C) 2011, Charlie Robbins & the Contributors
- * MIT LICENSE
- *
- */
-
- var util = require('util'),
- HttpStream = require('./http-stream');
-
- var STATUS_CODES = require('http').STATUS_CODES;
-
- //
- // ### function ResponseStream (options)
- //
- //
- var ResponseStream = module.exports = function (options) {
- var self = this,
- key;
-
- options = options || {};
- HttpStream.call(this, options);
-
- this.writeable = true;
- this.response = options.response;
-
- if (options.headers) {
- for (key in options.headers) {
- this.response.setHeader(key, options.headers[key]);
- }
- }
-
- //
- // Proxy `statusCode` changes to the actual `response.statusCode`.
- //
- Object.defineProperty(this, 'statusCode', {
- get: function () {
- return self.response.statusCode;
- },
- set: function (value) {
- self.response.statusCode = value;
- },
- enumerable: true,
- configurable: true
- });
-
- if (this.response) {
- this._headers = this.response._headers = this.response._headers || {};
-
- // Patch to node core
- this.response._headerNames = this.response._headerNames || {};
-
- //
- // Proxy to emit "header" event
- //
- this._renderHeaders = this.response._renderHeaders;
- this.response._renderHeaders = function () {
- if (!self._emittedHeader) {
- self._emittedHeader = true;
- self.headerSent = true;
- self._header = true;
- self.emit('header');
- }
-
- return self._renderHeaders.call(self.response);
- };
- }
- };
-
- util.inherits(ResponseStream, HttpStream);
-
- ResponseStream.prototype.writeHead = function (statusCode, statusMessage, headers) {
- if (typeof statusMessage === 'string') {
- this.response.statusMessage = statusMessage;
- } else {
- this.response.statusMessage = this.response.statusMessage
- || STATUS_CODES[statusCode] || 'unknown';
- headers = statusMessage;
- }
-
- this.response.statusCode = statusCode;
-
- if (headers) {
- var keys = Object.keys(headers);
- for (var i = 0; i < keys.length; i++) {
- var k = keys[i];
- if (k) this.response.setHeader(k, headers[k]);
- }
- }
- };
-
- //
- // Create pass-thru for the necessary
- // `http.ServerResponse` methods.
- //
- ['setHeader', 'getHeader', 'removeHeader', '_implicitHeader', 'addTrailers'].forEach(function (method) {
- ResponseStream.prototype[method] = function () {
- return this.response[method].apply(this.response, arguments);
- };
- });
-
- ResponseStream.prototype.json = function (obj) {
- if (!this.response.writable) {
- return;
- }
-
- if (typeof obj === 'number') {
- this.response.statusCode = obj;
- obj = arguments[1];
- }
-
- this.modified = true;
-
- if (!this.response._header && this.response.getHeader('content-type') !== 'application/json') {
- this.response.setHeader('content-type', 'application/json');
- }
-
- this.end(obj ? JSON.stringify(obj) : '');
- };
-
- ResponseStream.prototype.html = function (str) {
- if (!this.response.writable) {
- return;
- }
-
- if (typeof str === 'number') {
- this.response.statusCode = str;
- str = arguments[1];
- }
-
- this.modified = true;
-
- if (!this.response._header && this.response.getHeader('content-type') !== 'text/html') {
- this.response.setHeader('content-type', 'text/html');
- }
-
- this.end(str ? str: '');
- };
-
- ResponseStream.prototype.text = function (str) {
- if (!this.response.writable) {
- return;
- }
-
- if (typeof str === 'number') {
- this.response.statusCode = str;
- str = arguments[1];
- }
-
- this.modified = true;
-
- if (!this.response._header && this.response.getHeader('content-type') !== 'text/plain') {
- this.response.setHeader('content-type', 'text/plain');
- }
-
- this.end(str ? str: '');
- };
-
- ResponseStream.prototype.end = function (data) {
- if (data && this.writable) {
- this.emit('data', data);
- }
-
- this.modified = true;
- this.emit('end');
- };
-
- ResponseStream.prototype.pipe = function () {
- var self = this,
- dest;
-
- self.dest = dest = HttpStream.prototype.pipe.apply(self, arguments);
-
- dest.on('drain', function() {
- self.emit('drain')
- })
- return dest;
- };
-
- ResponseStream.prototype.write = function (data) {
- this.modified = true;
-
- if (this.writable) {
- return this.dest.write(data);
- }
- };
-
- ResponseStream.prototype.redirect = function (path, status) {
- var url = '';
-
- if (~path.indexOf('://')) {
- url = path;
- } else {
- url += this.req.connection.encrypted ? 'https://' : 'http://';
- url += this.req.headers.host;
- url += (path[0] === '/') ? path : '/' + path;
- }
-
- this.res.writeHead(status || 302, { 'Location': url });
- this.end();
- };
|