diff --git a/.gitignore b/.gitignore index 207febba..fe886a59 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ coverage node_modules npm-debug.log package-lock.json +.vscode diff --git a/index.js b/index.js index 40a442ba..a0de910e 100644 --- a/index.js +++ b/index.js @@ -66,6 +66,20 @@ var defer = typeof setImmediate === 'function' ? setImmediate : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } +function http2Fix() { + var http; + try { + http = require('http2'); + } catch (e) { + return; + } + if ( typeof (http.Http2ServerResponse.prototype._implicitHeader) !== 'function') { + http.Http2ServerResponse.prototype._implicitHeader = function () { + this.writeHead(this.statusCode); + }; + } +} + /** * Setup session store with the given `options`. * @@ -77,6 +91,7 @@ var defer = typeof setImmediate === 'function' * @param {Boolean} [options.resave] Resave unmodified sessions back to the store * @param {Boolean} [options.rolling] Enable/disable rolling session expiration * @param {Boolean} [options.saveUninitialized] Save uninitialized sessions to the store + * @param {Boolean} [options.useHttp2=false] Use http2 * @param {String|Array} [options.secret] Secret for signing session ID * @param {Object} [options.store=MemoryStore] Session store * @param {String} [options.unset] @@ -175,6 +190,9 @@ function session(options) { store.on('connect', function onconnect() { storeReady = true }) + if (options.useHttp2) { + http2Fix(); + } return function session(req, res, next) { // self-awareness diff --git a/package.json b/package.json index 711e9866..489de518 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "eslint": "7.32.0", "eslint-plugin-markdown": "2.2.1", "express": "4.17.3", + "get-port": "^5.1.1", "mocha": "10.0.0", "nyc": "15.1.0", "supertest": "6.2.3" diff --git a/test/session.js b/test/session.js index 7416b261..60d23788 100644 --- a/test/session.js +++ b/test/session.js @@ -6,7 +6,9 @@ var express = require('express') var fs = require('fs') var http = require('http') var https = require('https') +var http2 = require('http2') var request = require('supertest') +var getPort = require('get-port') var session = require('../') var SmartStore = require('./support/smart-store') var SyncStore = require('./support/sync-store') @@ -2040,6 +2042,64 @@ describe('session()', function(){ }) }) + describe('.http2 plain', function(){ + var app + var server + before(function () { + app = createRequestListener({ secret: 'keyboard cat', useHttp2: true }) + server = http2.createServer(app) + }) + + it('should set cookie with http2', function (done) { + + request(server).get('/').http2() + .expect(200) + .end(function(err, res) { + shouldSetCookie('connect.sid') + if (err) { + return done(err) + } + done(); + }); + }) + }) + + describe('.http2 secure', function(){ + var server + var uri + before(function (done) { + var app = createRequestListener({ secret: 'keyboard cat', useHttp2: true }) + var cert = fs.readFileSync(__dirname + '/fixtures/server.crt', 'ascii') + server = http2.createSecureServer({ + key: fs.readFileSync(__dirname + '/fixtures/server.key', 'ascii'), + cert: cert + }, app) + getPort().then(function(port) { + server.listen(port) + uri = 'https://localhost:' + port + done() + }).catch(function(err) { + return done(err) + }) + }) + after(function() { + server.close() + }) + + it('should set cookie with http2', function (done) { + + request(uri).get('/').http2() + .expect(200) + .end(function(err, res) { + shouldSetCookie('connect.sid') + if (err) { + return done(err) + } + done(); + }); + }) + }) + describe('.maxAge', function () { before(function (done) { var ctx = this diff --git a/test/support/env.js b/test/support/env.js index fba1bd89..51bab790 100644 --- a/test/support/env.js +++ b/test/support/env.js @@ -1,2 +1,3 @@ process.env.NO_DEPRECATION = 'express-session'; +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';