Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ class Test extends Request {

app.once('listening', onListening);
app.once('error', onError);
app.listen(0);
// Bind to the same address the client connects to. A wildcard bind can
// share its port with another process's 127.0.0.1 listener on macOS,
// and the request would then reach that process instead.
app.listen(0, '127.0.0.1');
}
addr = app.address();
}
Expand All @@ -98,8 +101,29 @@ class Test extends Request {
this._server = app;
}

// A SuperTest-created IPv6 wildcard is dual-stack by default. Prefer IPv4
// for that wildcard so SuperAgent does not construct an IPv6 loopback URL;
// Listening with a host resolves asynchronously, so the port is unknown
// until the server emits listening. end() fills it in before dispatch.
if (!addr) {
this._serverPath = path;
const protocol = app instanceof Server ? 'https' : 'http';
return protocol + '://127.0.0.1' + path;
}

return this.formatServerUrl(app, addr, path);
}

/**
* Builds a request URL from a listening server address.
*
* @param {Server} app
* @param {Object} addr
* @param {String} path
* @returns {String} URL address
* @api private
*/
formatServerUrl(app, addr, path) {
// Map wildcard addresses of servers passed in already listening to the
// IPv4 loopback so SuperAgent does not construct an IPv6 loopback URL;
// explicit IPv6-only servers retain their own address family below.
let host = addr.address;
if (host === '::') host = '127.0.0.1';
Expand Down Expand Up @@ -212,6 +236,10 @@ class Test extends Request {
dispatch = () => {
removeStartListeners();
try {
if (this._serverPath !== undefined) {
this.url = this.formatServerUrl(server, server.address(), this._serverPath);
this._serverPath = undefined;
}
super.end(finish);
} catch (err) {
finish(err);
Expand Down
12 changes: 12 additions & 0 deletions test/issue-fixes.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,18 @@ describe('GitHub Issue Fixes', function() {
.expect(200, 'supertest-server');
});
});

it('should bind the ephemeral server to the address it connects to', function() {
// A wildcard bind can share its port with another process's 127.0.0.1
// listener on macOS, and the client connection would reach that process.
const server = http.createServer(function(req, res) {
res.end(server.address().address);
});

return supertest(server)
.get('/')
.expect(200, '127.0.0.1');
});
});

describe('Issue #891: request timeout startup timing', function() {
Expand Down