Skip to content

Commit 22b89b6

Browse files
authoredOct 4, 2022
Merge pull request #793 from lamweili/feat/http2
feat: supports http2
2 parents a225e95 + da57804 commit 22b89b6

File tree

6 files changed

+145
-6
lines changed

6 files changed

+145
-6
lines changed
 

Diff for: ‎README.md

+31
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,37 @@ request(app)
5353
});
5454
```
5555

56+
To enable http2 protocol, simply append an options to `request` or `request.agent`:
57+
58+
```js
59+
const request = require('supertest');
60+
const express = require('express');
61+
62+
const app = express();
63+
64+
app.get('/user', function(req, res) {
65+
res.status(200).json({ name: 'john' });
66+
});
67+
68+
request(app, { http2: true })
69+
.get('/user')
70+
.expect('Content-Type', /json/)
71+
.expect('Content-Length', '15')
72+
.expect(200)
73+
.end(function(err, res) {
74+
if (err) throw err;
75+
});
76+
77+
request.agent(app, { http2: true })
78+
.get('/user')
79+
.expect('Content-Type', /json/)
80+
.expect('Content-Length', '15')
81+
.expect(200)
82+
.end(function(err, res) {
83+
if (err) throw err;
84+
});
85+
```
86+
5687
Here's an example with mocha, note how you can pass `done` straight to any of the `.expect()` calls:
5788

5889
```js

Diff for: ‎index.js

+22-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
*/
66
const methods = require('methods');
77
const http = require('http');
8+
let http2;
9+
try {
10+
http2 = require('http2'); // eslint-disable-line global-require
11+
} catch (_) {
12+
// eslint-disable-line no-empty
13+
}
814
const Test = require('./lib/test.js');
915
const agent = require('./lib/agent.js');
1016

@@ -16,16 +22,29 @@ const agent = require('./lib/agent.js');
1622
* @return {Test}
1723
* @api public
1824
*/
19-
module.exports = function(app) {
25+
module.exports = function(app, options = {}) {
2026
const obj = {};
2127

2228
if (typeof app === 'function') {
23-
app = http.createServer(app); // eslint-disable-line no-param-reassign
29+
if (options.http2) {
30+
if (!http2) {
31+
throw new Error(
32+
'supertest: this version of Node.js does not support http2'
33+
);
34+
}
35+
app = http2.createServer(app); // eslint-disable-line no-param-reassign
36+
} else {
37+
app = http.createServer(app); // eslint-disable-line no-param-reassign
38+
}
2439
}
2540

2641
methods.forEach(function(method) {
2742
obj[method] = function(url) {
28-
return new Test(app, method, url);
43+
var test = new Test(app, method, url);
44+
if (options.http2) {
45+
test.http2();
46+
}
47+
return test;
2948
};
3049
});
3150

Diff for: ‎lib/agent.js

+25-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
const { agent: Agent } = require('superagent');
88
const methods = require('methods');
99
const http = require('http');
10+
let http2;
11+
try {
12+
http2 = require('http2'); // eslint-disable-line global-require
13+
} catch (_) {
14+
// eslint-disable-line no-empty
15+
}
1016
const Test = require('./test.js');
1117

1218
/**
@@ -17,10 +23,24 @@ const Test = require('./test.js');
1723
* @api public
1824
*/
1925

20-
function TestAgent(app, options) {
26+
function TestAgent(app, options = {}) {
2127
if (!(this instanceof TestAgent)) return new TestAgent(app, options);
22-
if (typeof app === 'function') app = http.createServer(app); // eslint-disable-line no-param-reassign
28+
2329
Agent.call(this, options);
30+
this._options = options;
31+
32+
if (typeof app === 'function') {
33+
if (options.http2) {
34+
if (!http2) {
35+
throw new Error(
36+
'supertest: this version of Node.js does not support http2'
37+
);
38+
}
39+
app = http2.createServer(app); // eslint-disable-line no-param-reassign
40+
} else {
41+
app = http.createServer(app); // eslint-disable-line no-param-reassign
42+
}
43+
}
2444
this.app = app;
2545
}
2646

@@ -40,6 +60,9 @@ TestAgent.prototype.host = function(host) {
4060
methods.forEach(function(method) {
4161
TestAgent.prototype[method] = function(url, fn) { // eslint-disable-line no-unused-vars
4262
const req = new Test(this.app, method.toUpperCase(), url);
63+
if (this._options.http2) {
64+
req.http2();
65+
}
4366

4467
if (this._host) {
4568
req.set('host', this._host);

Diff for: ‎lib/test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
const { inspect } = require('util');
88
const { STATUS_CODES } = require('http');
9-
const { Server } = require('https');
9+
const { Server } = require('tls');
1010
const { deepStrictEqual } = require('assert');
1111
const { Request } = require('superagent');
1212

Diff for: ‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"mocha": "^10.0.0",
4646
"nock": "^13.2.8",
4747
"nyc": "^15.1.0",
48+
"proxyquire": "^2.1.3",
4849
"should": "^13.2.3"
4950
}
5051
}

Diff for: ‎test/supertest.js

+65
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
'use strict';
22

33
const https = require('https');
4+
let http2;
5+
try {
6+
http2 = require('http2'); // eslint-disable-line global-require
7+
} catch (_) {
8+
// eslint-disable-line no-empty
9+
}
410
const fs = require('fs');
511
const path = require('path');
612
const should = require('should');
@@ -1359,3 +1365,62 @@ describe('request.get(url).query(vals) works as expected', function () {
13591365
});
13601366
});
13611367
});
1368+
1369+
const describeHttp2 = (http2) ? describe : describe.skip;
1370+
describeHttp2('http2', function() {
1371+
// eslint-disable-next-line global-require
1372+
const proxyquire = require('proxyquire');
1373+
1374+
const tests = [
1375+
{
1376+
title: 'request(app)',
1377+
api: request,
1378+
mockApi: proxyquire('../index.js', { http2: null })
1379+
},
1380+
{
1381+
title: 'request.agent(app)',
1382+
api: request.agent,
1383+
mockApi: proxyquire('../lib/agent.js', { http2: null })
1384+
}
1385+
];
1386+
1387+
tests.forEach(({ title, api, mockApi }) => {
1388+
describe(title, function () {
1389+
const app = function(req, res) {
1390+
res.end('hey');
1391+
};
1392+
1393+
it('should fire up the app on an ephemeral port', function (done) {
1394+
api(app, { http2: true })
1395+
.get('/')
1396+
.end(function (err, res) {
1397+
res.status.should.equal(200);
1398+
res.text.should.equal('hey');
1399+
done();
1400+
});
1401+
});
1402+
1403+
it('should work with an active server', function (done) {
1404+
const server = http2.createServer(app);
1405+
1406+
server.listen(function () {
1407+
api(server)
1408+
.get('/')
1409+
.http2()
1410+
.end(function (err, res) {
1411+
res.status.should.equal(200);
1412+
res.text.should.equal('hey');
1413+
// close the external server explictly
1414+
server.close(done);
1415+
});
1416+
});
1417+
});
1418+
1419+
it('should throw error if http2 is not supported', function() {
1420+
(function() {
1421+
mockApi(app, { http2: true });
1422+
}).should.throw('supertest: this version of Node.js does not support http2');
1423+
});
1424+
});
1425+
});
1426+
});

0 commit comments

Comments
 (0)
Please sign in to comment.