testing/xpcshell/node-spdy/lib/spdy/response.js

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     1 var spdy = require('../spdy'),
     2     http = require('http'),
     3     res = http.ServerResponse.prototype;
     5 //
     6 // ### function _renderHeaders ()
     7 // Copy pasted from lib/http.js
     8 // (added lowercase)
     9 //
    10 exports._renderHeaders = function() {
    11   if (this._header) {
    12     throw new Error("Can't render headers after they are sent to the client.");
    13   }
    15   var keys = Object.keys(this._headerNames);
    16   for (var i = 0, l = keys.length; i < l; i++) {
    17     var key = keys[i];
    18     this._headerNames[key] = this._headerNames[key].toLowerCase();
    19   }
    21   return res._renderHeaders.call(this);
    22 };
    24 //
    25 // ### function writeHead (statusCode)
    26 // #### @statusCode {Number} HTTP Status code
    27 // .writeHead() wrapper
    28 // (Sorry, copy pasted from lib/http.js)
    29 //
    30 exports.writeHead = function(statusCode) {
    31   if (this._headerSent) return;
    32   this._headerSent = true;
    34   var reasonPhrase, headers, headerIndex;
    36   if (typeof arguments[1] == 'string') {
    37     reasonPhrase = arguments[1];
    38     headerIndex = 2;
    39   } else {
    40     reasonPhrase = http.STATUS_CODES[statusCode] || 'unknown';
    41     headerIndex = 1;
    42   }
    43   this.statusCode = statusCode;
    45   var obj = arguments[headerIndex];
    47   if (obj && this._headers) {
    48     // Slow-case: when progressive API and header fields are passed.
    49     headers = this._renderHeaders();
    51     // handle object case
    52     var keys = Object.keys(obj);
    53     for (var i = 0; i < keys.length; i++) {
    54       var k = keys[i];
    55       if (k) headers[k] = obj[k];
    56     }
    57   } else if (this._headers) {
    58     // only progressive api is used
    59     headers = this._renderHeaders();
    60   } else {
    61     // only writeHead() called
    62     headers = obj;
    63   }
    65   // cleanup
    66   this._header = '';
    68   // Do not send data to new connections after GOAWAY
    69   if (this.socket._isGoaway()) return;
    71   this.socket._lock(function() {
    72     var socket = this;
    74     this._framer.replyFrame(
    75       this.id,
    76       statusCode,
    77       reasonPhrase,
    78       headers,
    79       function (err, frame) {
    80         // TODO: Handle err
    81         socket.connection.write(frame);
    82         socket._unlock();
    83       }
    84     );
    85   });
    86 };
    88 //
    89 // ### function push (url, headers, callback)
    90 // #### @url {String} absolute or relative url (from root anyway)
    91 // #### @headers {Object} response headers
    92 // #### @callbacks {Function} continuation that will receive stream object
    93 // Initiates push stream
    94 //
    95 exports.push = function push(url, headers, priority, callback) {
    96   if (this.socket._destroyed) {
    97     return callback(Error('Can\'t open push stream, parent socket destroyed'));
    98   }
   100   if (!callback && typeof priority === 'function') {
   101     callback = priority;
   102     priority = 0;
   103   }
   105   if (!callback) callback = function() {};
   107   this.socket._lock(function() {
   108     var socket = this,
   109         id = socket.connection.pushId += 2,
   110         scheme = this._frame.headers.scheme,
   111         host = this._frame.headers.host || 'localhost',
   112         fullUrl = /^\//.test(url) ? scheme + '://' + host + url : url;
   114     this._framer.streamFrame(
   115       id,
   116       this.id,
   117       {
   118         method: 'GET',
   119         path: url,
   120         url: fullUrl,
   121         scheme: scheme,
   122         host: host,
   123         version: 'HTTP/1.1',
   124         priority: priority || 0
   125       },
   126       headers,
   127       function(err, frame) {
   128         if (err) {
   129           socket._unlock();
   130           callback(err);
   131         } else {
   132           socket.connection.write(frame);
   133           socket._unlock();
   135           var stream = new spdy.server.Stream(socket.connection, {
   136             type: 'SYN_STREAM',
   137             push: true,
   138             id: id,
   139             assoc: socket.id,
   140             priority: 0,
   141             headers: {}
   142           });
   144           socket.connection.streams[id] = stream;
   145           socket.pushes.push(stream);
   147           callback(null, stream);
   148         }
   149       }
   150     );
   151   });
   152 };

mercurial