1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/xpcshell/node-http2/test/http.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,422 @@ 1.4 +var expect = require('chai').expect; 1.5 +var util = require('./util'); 1.6 +var fs = require('fs'); 1.7 +var path = require('path'); 1.8 + 1.9 +var http2 = require('../lib/http'); 1.10 +var https = require('https'); 1.11 + 1.12 +process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; 1.13 + 1.14 +var options = { 1.15 + key: fs.readFileSync(path.join(__dirname, '../example/localhost.key')), 1.16 + cert: fs.readFileSync(path.join(__dirname, '../example/localhost.crt')), 1.17 + log: util.log 1.18 +}; 1.19 + 1.20 +http2.globalAgent = new http2.Agent({ log: util.log }); 1.21 + 1.22 +describe('http.js', function() { 1.23 + describe('Server', function() { 1.24 + describe('new Server(options)', function() { 1.25 + it('should throw if called without \'plain\' or TLS options', function() { 1.26 + expect(function() { 1.27 + new http2.Server(); 1.28 + }).to.throw(Error); 1.29 + expect(function() { 1.30 + http2.createServer(util.noop); 1.31 + }).to.throw(Error); 1.32 + }); 1.33 + }); 1.34 + describe('property `timeout`', function() { 1.35 + it('should be a proxy for the backing HTTPS server\'s `timeout` property', function() { 1.36 + var server = new http2.Server(options); 1.37 + var backingServer = server._server; 1.38 + var newTimeout = 10; 1.39 + server.timeout = newTimeout; 1.40 + expect(server.timeout).to.be.equal(newTimeout); 1.41 + expect(backingServer.timeout).to.be.equal(newTimeout); 1.42 + }); 1.43 + }); 1.44 + describe('method `setTimeout(timeout, [callback])`', function() { 1.45 + it('should be a proxy for the backing HTTPS server\'s `setTimeout` method', function() { 1.46 + var server = new http2.Server(options); 1.47 + var backingServer = server._server; 1.48 + var newTimeout = 10; 1.49 + var newCallback = util.noop; 1.50 + backingServer.setTimeout = function(timeout, callback) { 1.51 + expect(timeout).to.be.equal(newTimeout); 1.52 + expect(callback).to.be.equal(newCallback); 1.53 + }; 1.54 + server.setTimeout(newTimeout, newCallback); 1.55 + }); 1.56 + }); 1.57 + }); 1.58 + describe('Agent', function() { 1.59 + describe('property `maxSockets`', function() { 1.60 + it('should be a proxy for the backing HTTPS agent\'s `maxSockets` property', function() { 1.61 + var agent = new http2.Agent({ log: util.log }); 1.62 + var backingAgent = agent._httpsAgent; 1.63 + var newMaxSockets = backingAgent.maxSockets + 1; 1.64 + agent.maxSockets = newMaxSockets; 1.65 + expect(agent.maxSockets).to.be.equal(newMaxSockets); 1.66 + expect(backingAgent.maxSockets).to.be.equal(newMaxSockets); 1.67 + }); 1.68 + }); 1.69 + describe('method `request(options, [callback])`', function() { 1.70 + it('should throw when trying to use with \'http\' scheme', function() { 1.71 + expect(function() { 1.72 + var agent = new http2.Agent({ log: util.log }); 1.73 + agent.request({ protocol: 'http:' }); 1.74 + }).to.throw(Error); 1.75 + }); 1.76 + }); 1.77 + }); 1.78 + describe('OutgoingRequest', function() { 1.79 + function testFallbackProxyMethod(name, originalArguments, done) { 1.80 + var request = new http2.OutgoingRequest(); 1.81 + 1.82 + // When in HTTP/2 mode, this call should be ignored 1.83 + request.stream = { reset: util.noop }; 1.84 + request[name].apply(request, originalArguments); 1.85 + delete request.stream; 1.86 + 1.87 + // When in fallback mode, this call should be forwarded 1.88 + request[name].apply(request, originalArguments); 1.89 + var mockFallbackRequest = { on: util.noop }; 1.90 + mockFallbackRequest[name] = function() { 1.91 + expect(arguments).to.deep.equal(originalArguments); 1.92 + done(); 1.93 + }; 1.94 + request._fallback(mockFallbackRequest); 1.95 + } 1.96 + describe('method `setNoDelay(noDelay)`', function() { 1.97 + it('should act as a proxy for the backing HTTPS agent\'s `setNoDelay` method', function(done) { 1.98 + testFallbackProxyMethod('setNoDelay', [true], done); 1.99 + }); 1.100 + }); 1.101 + describe('method `setSocketKeepAlive(enable, initialDelay)`', function() { 1.102 + it('should act as a proxy for the backing HTTPS agent\'s `setSocketKeepAlive` method', function(done) { 1.103 + testFallbackProxyMethod('setSocketKeepAlive', [true, util.random(10, 100)], done); 1.104 + }); 1.105 + }); 1.106 + describe('method `setTimeout(timeout, [callback])`', function() { 1.107 + it('should act as a proxy for the backing HTTPS agent\'s `setTimeout` method', function(done) { 1.108 + testFallbackProxyMethod('setTimeout', [util.random(10, 100), util.noop], done); 1.109 + }); 1.110 + }); 1.111 + describe('method `abort()`', function() { 1.112 + it('should act as a proxy for the backing HTTPS agent\'s `abort` method', function(done) { 1.113 + testFallbackProxyMethod('abort', [], done); 1.114 + }); 1.115 + }); 1.116 + }); 1.117 + describe('test scenario', function() { 1.118 + describe('simple request', function() { 1.119 + it('should work as expected', function(done) { 1.120 + var path = '/x'; 1.121 + var message = 'Hello world'; 1.122 + 1.123 + var server = http2.createServer(options, function(request, response) { 1.124 + expect(request.url).to.equal(path); 1.125 + response.end(message); 1.126 + }); 1.127 + 1.128 + server.listen(1234, function() { 1.129 + http2.get('https://localhost:1234' + path, function(response) { 1.130 + response.on('readable', function() { 1.131 + expect(response.read().toString()).to.equal(message); 1.132 + server.close(); 1.133 + done(); 1.134 + }); 1.135 + }); 1.136 + }); 1.137 + }); 1.138 + }); 1.139 + describe('request with payload', function() { 1.140 + it('should work as expected', function(done) { 1.141 + var path = '/x'; 1.142 + var message = 'Hello world'; 1.143 + 1.144 + var server = http2.createServer(options, function(request, response) { 1.145 + expect(request.url).to.equal(path); 1.146 + request.once('readable', function() { 1.147 + expect(request.read().toString()).to.equal(message); 1.148 + response.end(); 1.149 + }); 1.150 + }); 1.151 + 1.152 + server.listen(1240, function() { 1.153 + var request = http2.request({ 1.154 + host: 'localhost', 1.155 + port: 1240, 1.156 + path: path 1.157 + }); 1.158 + request.write(message); 1.159 + request.end(); 1.160 + request.on('response', function() { 1.161 + server.close(); 1.162 + done(); 1.163 + }); 1.164 + }); 1.165 + }); 1.166 + }); 1.167 + describe('request with custom status code and headers', function() { 1.168 + it('should work as expected', function(done) { 1.169 + var path = '/x'; 1.170 + var message = 'Hello world'; 1.171 + var headerName = 'name'; 1.172 + var headerValue = 'value'; 1.173 + 1.174 + var server = http2.createServer(options, function(request, response) { 1.175 + // Request URL and headers 1.176 + expect(request.url).to.equal(path); 1.177 + expect(request.headers[headerName]).to.equal(headerValue); 1.178 + 1.179 + // A header to be overwritten later 1.180 + response.setHeader(headerName, 'to be overwritten'); 1.181 + expect(response.getHeader(headerName)).to.equal('to be overwritten'); 1.182 + 1.183 + // A header to be deleted 1.184 + response.setHeader('nonexistent', 'x'); 1.185 + response.removeHeader('nonexistent'); 1.186 + expect(response.getHeader('nonexistent')).to.equal(undefined); 1.187 + 1.188 + // Don't send date 1.189 + response.sendDate = false; 1.190 + 1.191 + // Specifying more headers, the status code and a reason phrase with `writeHead` 1.192 + var moreHeaders = {}; 1.193 + moreHeaders[headerName] = headerValue; 1.194 + response.writeHead(600, 'to be discarded', moreHeaders); 1.195 + expect(response.getHeader(headerName)).to.equal(headerValue); 1.196 + 1.197 + // Empty response body 1.198 + response.end(message); 1.199 + }); 1.200 + 1.201 + server.listen(1239, function() { 1.202 + var headers = {}; 1.203 + headers[headerName] = headerValue; 1.204 + var request = http2.request({ 1.205 + host: 'localhost', 1.206 + port: 1239, 1.207 + path: path, 1.208 + headers: headers 1.209 + }); 1.210 + request.end(); 1.211 + request.on('response', function(response) { 1.212 + expect(response.headers[headerName]).to.equal(headerValue); 1.213 + expect(response.headers['nonexistent']).to.equal(undefined); 1.214 + expect(response.headers['date']).to.equal(undefined); 1.215 + response.on('readable', function() { 1.216 + expect(response.read().toString()).to.equal(message); 1.217 + server.close(); 1.218 + done(); 1.219 + }); 1.220 + }); 1.221 + }); 1.222 + }); 1.223 + }); 1.224 + describe('request over plain TCP', function() { 1.225 + it('should work as expected', function(done) { 1.226 + var path = '/x'; 1.227 + var message = 'Hello world'; 1.228 + 1.229 + var server = http2.createServer({ 1.230 + plain: true, 1.231 + log: util.log 1.232 + }, function(request, response) { 1.233 + expect(request.url).to.equal(path); 1.234 + response.end(message); 1.235 + }); 1.236 + 1.237 + server.listen(1237, function() { 1.238 + var request = http2.request({ 1.239 + plain: true, 1.240 + host: 'localhost', 1.241 + port: 1237, 1.242 + path: path 1.243 + }, function(response) { 1.244 + response.on('readable', function() { 1.245 + expect(response.read().toString()).to.equal(message); 1.246 + server.close(); 1.247 + done(); 1.248 + }); 1.249 + }); 1.250 + request.end(); 1.251 + }); 1.252 + }); 1.253 + }); 1.254 + describe('request to an HTTPS/1 server', function() { 1.255 + it('should fall back to HTTPS/1 successfully', function(done) { 1.256 + var path = '/x'; 1.257 + var message = 'Hello world'; 1.258 + 1.259 + var server = https.createServer(options, function(request, response) { 1.260 + expect(request.url).to.equal(path); 1.261 + response.end(message); 1.262 + }); 1.263 + 1.264 + server.listen(5678, function() { 1.265 + http2.get('https://localhost:5678' + path, function(response) { 1.266 + response.on('readable', function() { 1.267 + expect(response.read().toString()).to.equal(message); 1.268 + done(); 1.269 + }); 1.270 + }); 1.271 + }); 1.272 + }); 1.273 + }); 1.274 + describe('HTTPS/1 request to a HTTP/2 server', function() { 1.275 + it('should fall back to HTTPS/1 successfully', function(done) { 1.276 + var path = '/x'; 1.277 + var message = 'Hello world'; 1.278 + 1.279 + var server = http2.createServer(options, function(request, response) { 1.280 + expect(request.url).to.equal(path); 1.281 + response.end(message); 1.282 + }); 1.283 + 1.284 + server.listen(1236, function() { 1.285 + https.get('https://localhost:1236' + path, function(response) { 1.286 + response.on('readable', function() { 1.287 + expect(response.read().toString()).to.equal(message); 1.288 + done(); 1.289 + }); 1.290 + }); 1.291 + }); 1.292 + }); 1.293 + }); 1.294 + describe('two parallel request', function() { 1.295 + it('should work as expected', function(done) { 1.296 + var path = '/x'; 1.297 + var message = 'Hello world'; 1.298 + 1.299 + var server = http2.createServer(options, function(request, response) { 1.300 + expect(request.url).to.equal(path); 1.301 + response.end(message); 1.302 + }); 1.303 + 1.304 + server.listen(1237, function() { 1.305 + done = util.callNTimes(2, done); 1.306 + // 1. request 1.307 + http2.get('https://localhost:1237' + path, function(response) { 1.308 + response.on('readable', function() { 1.309 + expect(response.read().toString()).to.equal(message); 1.310 + done(); 1.311 + }); 1.312 + }); 1.313 + // 2. request 1.314 + http2.get('https://localhost:1237' + path, function(response) { 1.315 + response.on('readable', function() { 1.316 + expect(response.read().toString()).to.equal(message); 1.317 + done(); 1.318 + }); 1.319 + }); 1.320 + }); 1.321 + }); 1.322 + }); 1.323 + describe('two subsequent request', function() { 1.324 + it('should use the same HTTP/2 connection', function(done) { 1.325 + var path = '/x'; 1.326 + var message = 'Hello world'; 1.327 + 1.328 + var server = http2.createServer(options, function(request, response) { 1.329 + expect(request.url).to.equal(path); 1.330 + response.end(message); 1.331 + }); 1.332 + 1.333 + server.listen(1238, function() { 1.334 + // 1. request 1.335 + http2.get('https://localhost:1238' + path, function(response) { 1.336 + response.on('readable', function() { 1.337 + expect(response.read().toString()).to.equal(message); 1.338 + 1.339 + // 2. request 1.340 + http2.get('https://localhost:1238' + path, function(response) { 1.341 + response.on('readable', function() { 1.342 + expect(response.read().toString()).to.equal(message); 1.343 + done(); 1.344 + }); 1.345 + }); 1.346 + }); 1.347 + }); 1.348 + }); 1.349 + }); 1.350 + }); 1.351 + describe('request and response with trailers', function() { 1.352 + it('should work as expected', function(done) { 1.353 + var path = '/x'; 1.354 + var message = 'Hello world'; 1.355 + var requestTrailers = { 'content-md5': 'x' }; 1.356 + var responseTrailers = { 'content-md5': 'y' }; 1.357 + 1.358 + var server = http2.createServer(options, function(request, response) { 1.359 + expect(request.url).to.equal(path); 1.360 + request.on('data', util.noop); 1.361 + request.once('end', function() { 1.362 + expect(request.trailers).to.deep.equal(requestTrailers); 1.363 + response.write(message); 1.364 + response.addTrailers(responseTrailers); 1.365 + response.end(); 1.366 + }); 1.367 + }); 1.368 + 1.369 + server.listen(1241, function() { 1.370 + var request = http2.request('https://localhost:1241' + path); 1.371 + request.addTrailers(requestTrailers); 1.372 + request.end(); 1.373 + request.on('response', function(response) { 1.374 + response.on('data', util.noop); 1.375 + response.once('end', function() { 1.376 + expect(response.trailers).to.deep.equal(responseTrailers); 1.377 + done(); 1.378 + }); 1.379 + }); 1.380 + }); 1.381 + }); 1.382 + }); 1.383 + describe('server push', function() { 1.384 + it('should work as expected', function(done) { 1.385 + var path = '/x'; 1.386 + var message = 'Hello world'; 1.387 + var pushedPath = '/y'; 1.388 + var pushedMessage = 'Hello world 2'; 1.389 + 1.390 + var server = http2.createServer(options, function(request, response) { 1.391 + expect(request.url).to.equal(path); 1.392 + var push1 = response.push('/y'); 1.393 + push1.end(pushedMessage); 1.394 + var push2 = response.push({ path: '/y', protocol: 'https:' }); 1.395 + push2.end(pushedMessage); 1.396 + response.end(message); 1.397 + }); 1.398 + 1.399 + server.listen(1235, function() { 1.400 + var request = http2.get('https://localhost:1235' + path); 1.401 + done = util.callNTimes(5, done); 1.402 + 1.403 + request.on('response', function(response) { 1.404 + response.on('readable', function() { 1.405 + expect(response.read().toString()).to.equal(message); 1.406 + done(); 1.407 + }); 1.408 + response.on('end', done); 1.409 + }); 1.410 + 1.411 + request.on('push', function(promise) { 1.412 + expect(promise.url).to.be.equal(pushedPath); 1.413 + promise.on('response', function(pushStream) { 1.414 + pushStream.on('readable', function() { 1.415 + expect(pushStream.read().toString()).to.equal(pushedMessage); 1.416 + done(); 1.417 + }); 1.418 + pushStream.on('end', done); 1.419 + }); 1.420 + }); 1.421 + }); 1.422 + }); 1.423 + }); 1.424 + }); 1.425 +});