Skip to content

Commit

Permalink
add isInjected property to request object (#4117)
Browse files Browse the repository at this point in the history
Implement `isInjected` read-only request property to indicate request created by `server.inject()`.
  • Loading branch information
neenhouse authored Aug 11, 2020
1 parent c31bd6d commit 783aa8a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 5 deletions.
6 changes: 6 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -4581,6 +4581,12 @@ Request information:

Note that the `request.info` object is not meant to be modified.

#### <a name="request.isInjected" /> `request.isInjected`

Access: read only.

`true` if the request was created via [`server.inject()`](#server.inject()), and `false` otherwise.

#### <a name="request.logs" /> `request.logs`

Access: read only.
Expand Down
8 changes: 7 additions & 1 deletion lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Transmit = require('./transmit');

const internals = {
events: Podium.validate(['finish', { name: 'peek', spread: true }, 'disconnect']),
reserved: ['server', 'url', 'query', 'path', 'method', 'mime', 'setUrl', 'setMethod', 'headers', 'id', 'app', 'plugins', 'route', 'auth', 'pre', 'preResponses', 'info', 'orig', 'params', 'paramsArray', 'payload', 'state', 'jsonp', 'response', 'raw', 'domain', 'log', 'logs', 'generateResponse']
reserved: ['server', 'url', 'query', 'path', 'method', 'mime', 'setUrl', 'setMethod', 'headers', 'id', 'app', 'plugins', 'route', 'auth', 'pre', 'preResponses', 'info', 'isInjected', 'orig', 'params', 'paramsArray', 'payload', 'state', 'jsonp', 'response', 'raw', 'domain', 'log', 'logs', 'generateResponse']
};


Expand All @@ -29,6 +29,7 @@ exports = module.exports = internals.Request = class {
this._eventContext = { request: this };
this._events = null; // Assigned an emitter when request.events is accessed
this._expectContinue = !!options.expectContinue;
this._isInjected = !!options.isInjected;
this._isPayloadPending = !!(req.headers['content-length'] || req.headers['transfer-encoding']); // Changes to false when incoming payload fully processed
this._isReplied = false; // true when response processing started
this._route = this._core.router.specials.notFound.route; // Used prior to routing (only settings are used, not the handler)
Expand Down Expand Up @@ -101,6 +102,11 @@ exports = module.exports = internals.Request = class {
return this._events;
}

get isInjected() {

return this._isInjected;
}

get url() {

if (this._urlError) {
Expand Down
3 changes: 2 additions & 1 deletion lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ internals.Server = class {
auth: options.auth,
allowInternals: options.allowInternals,
app: options.app,
plugins: options.plugins
plugins: options.plugins,
isInjected: true
});

const res = await Shot.inject(needle, settings);
Expand Down
3 changes: 1 addition & 2 deletions lib/transmit.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const Ammo = require('@hapi/ammo');
const Boom = require('@hapi/boom');
const Bounce = require('@hapi/bounce');
const Hoek = require('@hapi/hoek');
const Shot = require('@hapi/shot');
const Teamwork = require('@hapi/teamwork');

const Config = require('./config');
Expand Down Expand Up @@ -94,7 +93,7 @@ internals.transmit = function (response) {

// Connection: close

const isInjection = Shot.isInjection(request.raw.req);
const isInjection = request.isInjected;
if (!(isInjection || request._core.started) ||
request._isPayloadPending && !request.raw.req._readableState.ended) {

Expand Down
53 changes: 52 additions & 1 deletion test/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ describe('Core', () => {
expect(options.auth.artifacts).to.exist();
});

it('sets isInjected', async () => {
it('sets `request.auth.isInjected = true` when `auth` option is defined', async () => {

const server = Hapi.server();
server.route({ method: 'GET', path: '/', handler: (request) => request.auth.isInjected });
Expand All @@ -1134,6 +1134,57 @@ describe('Core', () => {
expect(res.result).to.be.true();
});

it('sets `request.isInjected = true` for requests created via `server.inject`', async () => {

const server = Hapi.server();
server.route({ method: 'GET', path: '/', handler: (request) => request.isInjected });

const options = {
url: '/'
};

const res = await server.inject(options);
expect(res.statusCode).to.equal(200);
expect(res.result).to.be.true();
});

it('`request.isInjected` access is read-only', async () => {

const server = Hapi.server();
server.route({ method: 'GET', path: '/', handler: (request) => {

const illegalAssignment = () => {

request.isInjected = false;
};

expect(illegalAssignment).to.throw('Cannot set property isInjected of [object Object] which has only a getter');

return request.isInjected;
} });

const options = {
url: '/'
};

const res = await server.inject(options);
expect(res.statusCode).to.equal(200);
expect(res.result).to.be.true();
});

it('sets `request.isInjected = false` for normal request', async () => {

const server = Hapi.server();
server.route({ method: 'GET', path: '/', handler: (request) => request.isInjected });

await server.start();

const { payload } = await Wreck.get(`http://localhost:${server.info.port}/`);
expect(payload.toString()).to.equal('false');

await server.stop();
});

it('sets app settings', async () => {

const server = Hapi.server();
Expand Down

0 comments on commit 783aa8a

Please sign in to comment.