Skip to content

Commit 4a4b8ec

Browse files
AlexGilleranmastermatt
authored andcommitted
feat(overrider): added support for header modifications before end()
* fix: added support for testing header modification with http-proxy * Remove pointless options.headers checks
1 parent 213014b commit 4a4b8ec

File tree

3 files changed

+94
-10
lines changed

3 files changed

+94
-10
lines changed

lib/interceptor.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,6 @@ Interceptor.prototype.reqheaderMatches = function reqheaderMatches(
193193
options,
194194
key
195195
) {
196-
// We don't try to match request headers if these weren't even specified in the request.
197-
if (!options.headers) {
198-
return true
199-
}
200-
201196
const reqHeader = this.reqheaders[key]
202197
let header = options.headers[key]
203198
if (header && typeof header !== 'string' && header.toString) {

lib/request_overrider.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ function setRequestHeaders(req, options, interceptor) {
3939
// NOTE: We use lower-case header field names throughout Nock.
4040
const HOST_HEADER = 'host'
4141
if (interceptor.__nock_filteredScope && interceptor.__nock_scopeHost) {
42-
if (options && options.headers) {
43-
options.headers[HOST_HEADER] = interceptor.__nock_scopeHost
44-
}
42+
options.headers[HOST_HEADER] = interceptor.__nock_scopeHost
4543
setHeader(req, HOST_HEADER, interceptor.__nock_scopeHost)
4644
} else {
4745
// For all other cases, we always add host header equal to the
@@ -233,6 +231,10 @@ function RequestOverrider(req, options, interceptors, remove) {
233231
/// like to change request.path in mid-flight.
234232
options.path = req.path
235233

234+
// similarly, node-http-proxy will modify headers in flight, so we have to put the headers back
235+
// into options
236+
options.headers = req.getHeaders()
237+
236238
// fixes #976
237239
options.protocol = `${options.proto}:`
238240

tests/test_intercept.js

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,11 @@ test('emits error if https route is missing', t => {
440440
t.equal(
441441
err.message.trim(),
442442
`Nock: No match for request ${JSON.stringify(
443-
{ method: 'GET', url: 'https://example.test/abcdef892932' },
443+
{
444+
method: 'GET',
445+
url: 'https://example.test/abcdef892932',
446+
headers: {},
447+
},
444448
null,
445449
2
446450
)}`
@@ -474,7 +478,11 @@ test('emits error if https route is missing', t => {
474478
t.equal(
475479
err.message.trim(),
476480
`Nock: No match for request ${JSON.stringify(
477-
{ method: 'GET', url: 'https://example.test:123/dsadsads' },
481+
{
482+
method: 'GET',
483+
url: 'https://example.test:123/dsadsads',
484+
headers: {},
485+
},
478486
null,
479487
2
480488
)}`
@@ -1340,3 +1348,82 @@ test('three argument form of http.request: URL, options, and callback', t => {
13401348
})
13411349
})
13421350
})
1351+
1352+
/*
1353+
* This test imitates a feature of node-http-proxy (https://github.com/nodejitsu/node-http-proxy) -
1354+
* modifying headers for an in-flight request by modifying them.
1355+
*/
1356+
test('works when headers are removed on the socket event', t => {
1357+
// Set up a nock that will fail if it gets an "authorization" header.
1358+
const serviceScope = nock('http://service', {
1359+
badheaders: ['authorization'],
1360+
})
1361+
.get('/endpoint')
1362+
.reply(200)
1363+
1364+
// Create a server to act as our reverse proxy.
1365+
const server = http.createServer((request, response) => {
1366+
// Make a request to the nock instance with the same request that came in.
1367+
const proxyReq = http.request({
1368+
host: 'service',
1369+
// Get the path from the incoming request and pass it through
1370+
path: `/${request.url
1371+
.split('/')
1372+
.slice(1)
1373+
.join('/')}`,
1374+
headers: request.headers,
1375+
})
1376+
1377+
// When we connect, remove the authorization header (node-http-proxy uses this event to do it)
1378+
proxyReq.on('socket', function() {
1379+
proxyReq.removeHeader('authorization')
1380+
1381+
// End the request here, otherwise it ends up matching the request before socket gets called
1382+
// because socket runs on process.nextTick
1383+
proxyReq.end()
1384+
})
1385+
1386+
proxyReq.on('response', proxyRes => {
1387+
proxyRes.pipe(response)
1388+
})
1389+
1390+
proxyReq.on('error', error => {
1391+
console.error(error)
1392+
t.error(error)
1393+
t.end()
1394+
})
1395+
})
1396+
1397+
server
1398+
.listen(() => {
1399+
// Now that the server's started up, make a request to it with an authorization header.
1400+
const req = http.request(
1401+
{
1402+
hostname: 'localhost',
1403+
path: '/endpoint',
1404+
port: server.address().port,
1405+
method: 'GET',
1406+
headers: {
1407+
authorization: 'blah',
1408+
},
1409+
},
1410+
res => {
1411+
// If we get a request, all good :)
1412+
t.equal(200, res.statusCode)
1413+
serviceScope.done()
1414+
server.close(t.end)
1415+
}
1416+
)
1417+
1418+
req.on('error', error => {
1419+
t.error(error)
1420+
t.end()
1421+
})
1422+
1423+
req.end()
1424+
})
1425+
.on('error', error => {
1426+
t.error(error)
1427+
t.end()
1428+
})
1429+
})

0 commit comments

Comments
 (0)