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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial