Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hapi

Package Overview
Dependencies
Maintainers
1
Versions
295
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hapi - npm Package Compare versions

Comparing version 17.0.0-rc1 to 17.0.0-rc2

lib/headers.js

49

lib/auth.js

@@ -83,3 +83,8 @@ 'use strict';

this.settings.default = this._setupRoute(Hoek.clone(options)); // Can change options
this.settings.default = this._setupRoute(Hoek.clone(options)); // Prevent changes to options
const routes = this.server._router.table();
for (let i = 0; i < routes.length; ++i) {
routes[i].rebuild();
}
};

@@ -96,3 +101,3 @@

const realm = strategy.realm;
const response = await request.server._replier.execute(strategy.methods.authenticate, request, { bind, realm, auth: true });
const response = await request.server._responder.execute(strategy.methods.authenticate, request, { bind, realm, auth: true });

@@ -210,2 +215,25 @@ if (!response.isAuth) {

internals.Auth.prototype._enabled = function (route, type) {
const config = this.lookup(route);
if (!config) {
return false;
}
if (type === 'authenticate') {
return true;
}
for (let i = 0; i < config.strategies.length; ++i) {
const name = config.strategies[i];
const strategy = this._strategies[name];
if (strategy.methods[type]) {
return true;
}
}
return false;
};
internals.Auth.authenticate = function (request) {

@@ -238,6 +266,2 @@

const config = this.lookup(request.route);
if (!config) {
return;
}
return internals.authenticate(config, request, this);

@@ -270,3 +294,3 @@ };

const realm = strategy.realm;
const response = await request.server._replier.execute(strategy.methods.payload, request, { bind, realm });
const response = await request.server._responder.execute(strategy.methods.payload, request, { bind, realm });

@@ -287,5 +311,3 @@ if (response &&

const auth = request.server.auth;
const config = auth.lookup(request.route);
if (!config ||
!request.auth.isAuthenticated ||
if (!request.auth.isAuthenticated ||
request.auth.strategy === 'bypass') {

@@ -303,3 +325,6 @@

const realm = strategy.realm;
return await request.server._replier.execute(strategy.methods.response, request, { bind, realm, continue: 'undefined' });
const error = await request.server._responder.execute(strategy.methods.response, request, { bind, realm, continue: 'undefined' });
if (error) {
throw error;
}
};

@@ -328,3 +353,3 @@

const realm = strategy.realm;
const response = await request.server._replier.execute(strategy.methods.authenticate, request, { bind, realm, auth: true });
const response = await request.server._responder.execute(strategy.methods.authenticate, request, { bind, realm, auth: true });

@@ -331,0 +356,0 @@ const message = (response.isAuth ? internals.validate(response.error, response.data, name, config, request, errors) : internals.validate(response, null, name, config, request, errors));

@@ -62,6 +62,8 @@ 'use strict';

internals.Compression.prototype.encoding = function (response) {
internals.Compression.prototype.encoding = function (response, length) {
const request = response.request;
if (!request.server.settings.compression) {
if (!request.server.settings.compression ||
(length !== null && length < request.server.settings.compression.minBytes)) {
return null;

@@ -68,0 +70,0 @@ }

@@ -86,3 +86,3 @@ 'use strict';

internals.handler = function (request, reply) {
internals.handler = function (request, responder) {

@@ -131,3 +131,3 @@ // Validate CORS preflight request

const response = reply();
const response = responder.wrap();
response._header('access-control-allow-origin', request.headers.origin);

@@ -150,13 +150,6 @@ response._header('access-control-allow-methods', method);

exports.headers = function (response) {
exports.headers = function (request) {
const request = response.request;
if (request._route._special) {
return;
}
const settings = request.route.settings.cors;
if (!settings) {
return;
}
const response = request.response;

@@ -163,0 +156,0 @@ response.vary('origin');

@@ -14,6 +14,5 @@ 'use strict';

exports.server = {
compression: true, // Enable response compression
compression: {}, // Enable response compression
debug: {
request: ['implementation'],
log: ['implementation']
request: ['implementation']
},

@@ -44,3 +43,3 @@ load: {

},
log: false, // Enables request level log collection
log: {}, // Enables request level log generation and collection
payload: {

@@ -47,0 +46,0 @@ failAction: 'error',

@@ -39,3 +39,3 @@ 'use strict';

const node = {
func: methods[i], // Request: function (request, reply), Server: function (server)
func: methods[i], // Request: function (request, responder), Server: function (server)
bind: options.bind,

@@ -42,0 +42,0 @@ plugin: event.plugin

@@ -15,32 +15,30 @@ 'use strict';

try {
// Prerequisites
// Prerequisites
if (request._route._prerequisites) {
for (let i = 0; i < request._route._prerequisites.length; ++i) { // Serial execution of each set
const set = request._route._prerequisites[i];
const pres = [];
for (let j = 0; j < set.length; ++j) {
pres.push(internals.handler(request, set[j].method, set[j]));
}
if (request._route._prerequisites) {
for (let i = 0; i < request._route._prerequisites.length; ++i) { // Serial execution of each set
const set = request._route._prerequisites[i];
const pres = [];
for (let j = 0; j < set.length; ++j) {
pres.push(internals.handler(request, set[j].method, set[j]));
}
const responses = await Promise.all(pres); // Parallel execution within sets
const responses = await Promise.all(pres); // Parallel execution within sets
for (let j = 0; j < responses.length; ++j) {
if (responses[j] !== undefined) {
request._setResponse(responses[j]);
return;
}
for (let j = 0; j < responses.length; ++j) {
if (responses[j] !== undefined) {
return responses[j];
}
}
}
}
// Handler
// Handler
const result = await internals.handler(request, request.route.settings.handler);
request._setResponse(result);
const result = await internals.handler(request, request.route.settings.handler);
if (result._takeover) {
return result;
}
catch (err) {
request._setResponse(err);
}
request._setResponse(result);
};

@@ -53,3 +51,3 @@

const realm = request.route.realm;
const response = await request.server._replier.execute(method, request, { bind, realm, continue: 'null' });
const response = await request.server._responder.execute(method, request, { bind, realm, continue: 'null' });

@@ -137,9 +135,9 @@ // Handler

[
function (request, reply) { },
function (request, responder) { },
{
method: function (request, reply) { }
method: function (request, responder) { }
assign: key1
},
{
method: function (request, reply) { },
method: function (request, responder) { },
assign: key2

@@ -149,3 +147,3 @@ }

{
method: function (request, reply) { },
method: function (request, responder) { },
assign: key3

@@ -152,0 +150,0 @@ }

@@ -249,3 +249,3 @@ 'use strict';

Hoek.assert(['reply', 'request', 'server'].indexOf(type) !== -1, 'Unknown decoration type:', type);
Hoek.assert(['responder', 'request', 'server'].indexOf(type) !== -1, 'Unknown decoration type:', type);
Hoek.assert(property, 'Missing decoration property name');

@@ -265,7 +265,7 @@ Hoek.assert(typeof property === 'string', 'Decoration property must be a string');

// Reply
// Responder
if (type === 'reply') {
this.root._replier.decorate(property, method);
this.root.decorations.reply.push(property);
if (type === 'responder') {
this.root._responder.decorate(property, method);
this.root.decorations.responder.push(property);
return;

@@ -272,0 +272,0 @@ }

@@ -98,3 +98,3 @@ 'use strict';

this._setUrl(req.url, this.server.settings.router.stripTrailingSlash); // Sets: this.url, this.path, this.query
this._setMethod(req.method); // Sets: this.method
this._setMethod(req.method); // Sets: this.method

@@ -109,3 +109,3 @@ this.id = now + ':' + server.info.id + ':' + server._requestCounter.value++;

this._route = this.server._router.specials.notFound.route; // Used prior to routing (only settings are used, not the handler)
this._route = this.server._router.specials.notFound.route; // Used prior to routing (only settings are used, not the handler)
this.route = this._route.public;

@@ -143,3 +143,3 @@

this._states = {};
this._entity = {}; // Entity information set via reply.entity()
this._entity = {}; // Entity information set via responder.entity()
this._logger = [];

@@ -163,9 +163,11 @@ this._allowInternals = !!options.allowInternals;

const about = {
method: this.method,
url: this.url.href,
agent: this.raw.req.headers['user-agent']
};
if (this.route.settings.log.stats) {
const about = {
method: this.method,
url: this.url.href,
agent: this.raw.req.headers['user-agent']
};
this._log(['received'], about, now); // Must be last for object to be fully constructed
this._log(['received'], about, now); // Must be last for object to be fully constructed
}
}

@@ -274,3 +276,3 @@

if (this.route.settings.log) {
if (this.route.settings.log.collect) {
if (typeof data === 'function') {

@@ -293,3 +295,3 @@ update = update();

Hoek.assert(this.route.settings.log, 'Request logging is disabled');
Hoek.assert(this.route.settings.log.collect, 'Request logging is disabled');

@@ -346,4 +348,3 @@ if (typeof tags === 'boolean') {

if (response) {
await this._reply(response);
return;
return this._reply(response);
}

@@ -360,4 +361,3 @@ }

await this._reply(Boom.badRequest('Invalid path'));
return;
return this._reply(Boom.badRequest('Invalid path'));
}

@@ -390,13 +390,16 @@

for (let i = 0; i < this._route._cycle.length; ++i) {
if (this._isReplied) {
return;
}
await this._lifecycle(this._route._cycle, false);
this._reply();
}
if (this._isBailed) {
await this._reply();
async _lifecycle(cycle, postCycle) {
for (let i = 0; i < cycle.length; ++i) {
if ((this._isReplied && !postCycle) ||
this._isBailed) {
return;
}
const func = this._route._cycle[i];
const func = cycle[i];
let response;

@@ -412,14 +415,17 @@ try {

catch (err) {
response = err;
response = Response.wrap(err, this);
}
if (response &&
response !== this.server._replier.continue) {
response !== this.server._responder.continue) {
await this._reply(response);
return;
this._setResponse(response);
if (!postCycle ||
typeof response === 'symbol') {
return;
}
}
}
await this._reply();
}

@@ -436,16 +442,18 @@

let serverTimeout = this.route.settings.timeout.server;
if (serverTimeout) {
serverTimeout = Math.floor(serverTimeout - this._bench.elapsed()); // Calculate the timeout from when the request was constructed
const timeoutReply = () => {
if (!serverTimeout) {
return;
}
this._log(['request', 'server', 'timeout', 'error'], { timeout: serverTimeout, elapsed: this._bench.elapsed() });
this._reply(Boom.serverUnavailable()).then(Hoek.ignore);
};
serverTimeout = Math.floor(serverTimeout - this._bench.elapsed()); // Calculate the timeout from when the request was constructed
const timeoutReply = () => {
if (serverTimeout <= 0) {
return timeoutReply();
}
this._log(['request', 'server', 'timeout', 'error'], { timeout: serverTimeout, elapsed: this._bench.elapsed() });
this._reply(Boom.serverUnavailable());
};
this._serverTimeoutId = setTimeout(timeoutReply, serverTimeout);
if (serverTimeout <= 0) {
return timeoutReply();
}
this._serverTimeoutId = setTimeout(timeoutReply, serverTimeout);
}

@@ -459,3 +467,3 @@

const realm = ext.plugin.realm;
const response = await this.server._replier.execute(ext.func, this, { bind, realm });
const response = await this.server._responder.execute(ext.func, this, { bind, realm });

@@ -465,3 +473,3 @@ // Process response

if (typeof response === 'symbol') {
if (response === this.server._replier.continue) {
if (response === this.server._responder.continue) {
continue;

@@ -510,28 +518,23 @@ }

if (this.response === this.server._replier.close) {
this.raw.res.end(); // End the response in case it wasn't already closed
if (typeof this.response === 'symbol') { // close or abort
this._abort();
return;
}
if (this.response === this.server._replier.abandon ||
this.response === this.server._replier.close) {
this._finalize();
await this._lifecycle(this._route._postCycle, true);
if (typeof this.response === 'symbol') { // close or abort
this._abort();
return;
}
if (this.server.root._extensions.route.onPreResponse.nodes) {
let response;
try {
response = await this._invoke(this.server.root._extensions.route.onPreResponse);
}
catch (err) {
response = err;
}
await Transmit.send(this);
this._finalize();
}
if (response) {
this._setResponse(response);
}
_abort() {
if (this.response === this.server._responder.close) {
this.raw.res.end(); // End the response in case it wasn't already closed
}
await Transmit.send(this);
this._finalize();

@@ -538,0 +541,0 @@ }

@@ -484,10 +484,10 @@ 'use strict';

let source = this.source;
// Processor marshal
try {
if (!this._processors.marshal) {
this._streamify(this.source);
return;
if (this._processors.marshal) {
source = await this._processors.marshal(this);
}
const source = await this._processors.marshal(this);
this._streamify(source);
}

@@ -497,5 +497,4 @@ catch (err) {

}
}
_streamify(source) {
// Stream source

@@ -508,3 +507,3 @@ if (source instanceof Stream) {

if (source._readableState.objectMode) {
throw Boom.badImplementation('Cannot reply with stream in object mode');
throw Boom.badImplementation('Cannot responder with stream in object mode');
}

@@ -516,7 +515,15 @@

// Plain source (non string or null)
const jsonify = (this.variety === 'plain' && source !== null && typeof source !== 'string');
if (!jsonify &&
this.settings.stringify) {
throw Boom.badImplementation('Cannot set formatting options on non object response');
}
let payload = source;
if (this.variety === 'plain' &&
source !== null &&
typeof source !== 'string') {
if (jsonify) {
const options = this.settings.stringify || {};

@@ -527,7 +534,13 @@ const space = options.space || this.request.route.settings.json.space;

const escape = this.request.route.settings.json.escape || false;
if (replacer || space) {
payload = JSON.stringify(payload, replacer, space);
try {
if (replacer || space) {
payload = JSON.stringify(payload, replacer, space);
}
else {
payload = JSON.stringify(payload);
}
}
else {
payload = JSON.stringify(payload);
catch (err) {
throw Boom.boomify(err);
}

@@ -543,5 +556,2 @@

}
else if (this.settings.stringify) {
throw Boom.badImplementation('Cannot set formatting options on non object response');
}

@@ -579,2 +589,6 @@ this._payload = new internals.Response.Payload(payload, this.settings);

if (stream.unpipe) {
stream.unpipe();
}
if (stream.close) {

@@ -648,2 +662,19 @@ stream.close();

}
writeToStream(stream) {
if (this._prefix) {
stream.write(this._prefix, this._encoding);
}
if (this._data) {
stream.write(this._data, this._encoding);
}
if (this._suffix) {
stream.write(this._suffix, this._encoding);
}
stream.end();
}
};

@@ -650,0 +681,0 @@

@@ -14,2 +14,3 @@ 'use strict';

const Handler = require('./handler');
const Headers = require('./headers');
const Schema = require('./schema');

@@ -191,2 +192,3 @@ const Security = require('./security');

this._cycle = [internals.drain, Handler.execute];
this.rebuild();
return;

@@ -208,10 +210,13 @@ }

this._extensions[event.type].add(event);
if (event.type === 'onPreResponse') {
return;
}
}
if (this._special) {
this._postCycle = (this._extensions.onPreResponse.nodes ? [this._extensions.onPreResponse] : []);
this._marshalCycle = [Headers.type, Headers.content];
return;
}
// Build lifecycle array
const cycle = [];
this._cycle = [];

@@ -221,23 +226,22 @@ // 'onRequest'

if (this.settings.jsonp) {
cycle.push(internals.parseJSONP);
this._cycle.push(internals.parseJSONP);
}
if (this.settings.state.parse) {
cycle.push(internals.state);
this._cycle.push(internals.state);
}
if (this._extensions.onPreAuth.nodes) {
cycle.push(this._extensions.onPreAuth);
this._cycle.push(this._extensions.onPreAuth);
}
const authenticate = (this.settings.auth !== false); // Anything other than 'false' can still require authentication
if (authenticate) {
cycle.push(Auth.authenticate);
if (this.server.auth._enabled(this, 'authenticate')) {
this._cycle.push(Auth.authenticate);
}
if (this.method !== 'get') {
cycle.push(internals.payload);
this._cycle.push(internals.payload);
if (authenticate) {
cycle.push(Auth.payload);
if (this.server.auth._enabled(this, 'payload')) {
this._cycle.push(Auth.payload);
}

@@ -247,42 +251,65 @@ }

if (this._extensions.onPostAuth.nodes) {
cycle.push(this._extensions.onPostAuth);
this._cycle.push(this._extensions.onPostAuth);
}
if (this.settings.validate.headers) {
cycle.push(Validation.headers);
this._cycle.push(Validation.headers);
}
if (this.settings.validate.params) {
cycle.push(Validation.params);
this._cycle.push(Validation.params);
}
if (this.settings.jsonp) {
cycle.push(internals.cleanupJSONP);
this._cycle.push(internals.cleanupJSONP);
}
if (this.settings.validate.query) {
cycle.push(Validation.query);
this._cycle.push(Validation.query);
}
if (this.settings.validate.payload) {
cycle.push(Validation.payload);
this._cycle.push(Validation.payload);
}
if (this._extensions.onPreHandler.nodes) {
cycle.push(this._extensions.onPreHandler);
this._cycle.push(this._extensions.onPreHandler);
}
cycle.push(Handler.execute); // Must not call next() with an Error
this._cycle.push(Handler.execute);
if (this._extensions.onPostHandler.nodes) {
cycle.push(this._extensions.onPostHandler); // An error from here on will override any result set in handler()
this._cycle.push(this._extensions.onPostHandler);
}
this._postCycle = [];
if (this.settings.response._validate &&
this.settings.response.sample !== 0) {
cycle.push(Validation.response);
this._postCycle.push(Validation.response);
}
this._cycle = cycle;
if (this._extensions.onPreResponse.nodes) {
this._postCycle.push(this._extensions.onPreResponse);
}
this._marshalCycle = [Headers.type];
if (this.settings.cors) {
this._marshalCycle.push(Cors.headers);
}
if (this.settings.security) {
this._marshalCycle.push(Security.headers);
}
this._marshalCycle.push(Headers.unmodified);
this._marshalCycle.push(Headers.cache);
this._marshalCycle.push(Headers.state);
this._marshalCycle.push(Headers.content);
if (this.server.auth._enabled(this, 'response')) {
this._marshalCycle.push(Auth.response); // Must be last in case requires access to headers
}
};

@@ -365,3 +392,3 @@

// failAction: 'error', 'log', 'ignore', function (request, reply, error)
// failAction: 'error', 'log', 'ignore', function (request, responder, error)

@@ -389,3 +416,3 @@ const failAction = request.route.settings.payload.failAction;

return await request.server._replier.execute(failAction, request, { realm: request.route.realm, args: [err] });
return await request.server._responder.execute(failAction, request, { realm: request.route.realm, args: [err] });
}

@@ -392,0 +419,0 @@ };

@@ -101,3 +101,6 @@ 'use strict';

jsonp: Joi.string(),
log: Joi.boolean(),
log: Joi.object({
stats: Joi.boolean().default(false),
collect: Joi.boolean().default(false)
}),
payload: Joi.object({

@@ -190,3 +193,6 @@ output: Joi.string().valid('data', 'stream', 'file'),

cache: Joi.allow(null), // Validated elsewhere
compression: Joi.boolean(),
compression: Joi.object({
minBytes: Joi.number().min(1).integer().default(1024)
})
.allow(false),
debug: Joi.object({

@@ -193,0 +199,0 @@ request: Joi.array().items(Joi.string()).single().allow(false),

@@ -64,28 +64,26 @@ 'use strict';

exports.headers = function (response) {
exports.headers = function (request) {
const request = response.request;
const response = request.response;
const security = response.request.route.settings.security;
const security = request.route.settings.security;
if (security) {
if (security._hsts) {
response._header('strict-transport-security', security._hsts, { override: false });
}
if (security._hsts) {
response._header('strict-transport-security', security._hsts, { override: false });
}
if (security._xframe) {
response._header('x-frame-options', security._xframe, { override: false });
}
if (security._xframe) {
response._header('x-frame-options', security._xframe, { override: false });
}
if (security.xss) {
response._header('x-xss-protection', '1; mode=block', { override: false });
}
if (security.xss) {
response._header('x-xss-protection', '1; mode=block', { override: false });
}
if (security.noOpen) {
response._header('x-download-options', 'noopen', { override: false });
}
if (security.noOpen) {
response._header('x-download-options', 'noopen', { override: false });
}
if (security.noSniff) {
response._header('x-content-type-options', 'nosniff', { override: false });
}
if (security.noSniff) {
response._header('x-content-type-options', 'nosniff', { override: false });
}
};

@@ -27,3 +27,3 @@ 'use strict';

const Plugin = require('./plugin');
const Reply = require('./reply');
const Responder = require('./responder');
const Request = require('./request');

@@ -66,3 +66,3 @@ const Route = require('./route');

this._decorations = {};
this.decorations = { request: [], reply: [], server: [] };
this.decorations = { request: [], responder: [], server: [] };
this._dependencies = []; // Plugin dependencies

@@ -73,3 +73,3 @@ this._events = new Podium(internals.events);

this._registrations = {}; // Tracks plugin for dependency validation { name -> { version } }
this._replier = new Reply();
this._responder = new Responder();
this._requestor = new Request();

@@ -474,3 +474,3 @@ this._plugins = {}; // Exposed plugin properties by name

internals.notFound = function (request, reply) {
internals.notFound = function () {

@@ -481,3 +481,3 @@ throw Boom.notFound();

internals.badRequest = function (request, reply) {
internals.badRequest = function () {

@@ -522,3 +522,3 @@ throw Boom.badRequest();

request._execute().then();
request._execute();
}

@@ -525,0 +525,0 @@ };

@@ -6,3 +6,2 @@ 'use strict';

const Http = require('http');
const Stream = require('stream');

@@ -15,6 +14,3 @@ const Ammo = require('ammo');

const Auth = require('./auth');
const Cors = require('./cors');
const Response = require('./response');
const Security = require('./security');

@@ -47,59 +43,6 @@

const response = request.response;
Cors.headers(response);
internals.content(response, false);
Security.headers(response);
internals.unmodified(response);
try {
await internals.state(response);
for (let i = 0; i < request._route._marshalCycle.length; ++i) {
const func = request._route._marshalCycle[i];
await func(request);
}
catch (err) {
request._log(['state', 'response', 'error'], err);
request._states = {}; // Clear broken state
throw err;
}
internals.cache(response);
if (response._isPayloadSupported() ||
request.method === 'head') {
await response._marshal();
if (request.jsonp &&
response._payload.jsonp) {
response._header('content-type', 'text/javascript' + (response.settings.charset ? '; charset=' + response.settings.charset : ''));
response._header('x-content-type-options', 'nosniff');
response._payload.jsonp(request.jsonp);
}
if (response._payload.size &&
typeof response._payload.size === 'function') {
response._header('content-length', response._payload.size(), { override: false });
}
if (!response._isPayloadSupported()) {
response._close(); // Close unused file streams
response._payload = new internals.Empty(); // Set empty stream
}
internals.content(response, true);
}
else {
// Set empty stream
response._close(); // Close unused file streams
response._payload = new internals.Empty();
delete response.headers['content-length'];
}
const authError = await Auth.response(request); // Must be last in case requires access to headers
if (authError) {
throw authError;
}
};

@@ -140,3 +83,3 @@

const request = response.request;
const length = parseInt(response.headers['content-length'], 10); // In case value is a string
const length = internals.length(response);

@@ -155,3 +98,3 @@ // Empty response

const encoding = request.server.root._compression.encoding(response);
const encoding = request.server.root._compression.encoding(response, length);

@@ -164,3 +107,3 @@ // Range

response.statusCode === 200 &&
length > 0 &&
length &&
!encoding) {

@@ -203,3 +146,2 @@

if (encoding &&
length !== 0 &&
response.statusCode !== 206 &&

@@ -244,10 +186,31 @@ response._isPayloadSupported()) {

return internals.pipe(response, compressor, ranger);
// Finalize response stream
const stream = internals.chain([response._payload, response._tap(), compressor, ranger]);
return internals.pipe(request, stream);
};
internals.pipe = function (response, compressor, ranger) {
internals.length = function (response) {
const request = response.request;
const source = response._payload;
const header = response.headers['content-length'];
if (header === undefined) {
return null;
}
if (typeof header === 'string') {
const length = parseInt(header, 10);
if (!isFinite(length)) {
return null;
}
return length;
}
return header;
};
internals.pipe = function (request, stream) {
const team = new Teamwork.Team({ meetings: 1 });

@@ -259,3 +222,3 @@

source.removeListener('error', end);
stream.removeListener('error', end);

@@ -277,4 +240,3 @@ request.raw.req.removeListener('aborted', onAborted);

source.unpipe();
Response.drain(source);
Response.drain(stream);
}

@@ -288,15 +250,18 @@

if ((event || err) &&
request._events) {
if (event ||
err) {
request._events.emit('disconnect');
if (request._events) {
request._events.emit('disconnect');
}
request._log(event ? ['response', 'error', event] : ['response', 'error'], err);
}
else if (request.route.settings.log.stats) {
request._log(['response'], err);
}
const tags = (err ? ['response', 'error'] : (event ? ['response', 'error', event] : ['response']));
request._log(tags, err);
team.attend();
};
source.once('error', end);
const onAborted = () => end(null, 'aborted');

@@ -312,7 +277,9 @@ const onClose = () => end(null, 'close');

const tap = response._tap();
const preview = (tap ? source.pipe(tap) : source);
const compressed = (compressor ? preview.pipe(compressor) : preview);
const ranged = (ranger ? compressed.pipe(ranger) : compressed);
ranged.pipe(request.raw.res);
if (stream.writeToStream) {
stream.writeToStream(request.raw.res);
}
else {
stream.once('error', end);
stream.pipe(request.raw.res);
}

@@ -360,148 +327,14 @@ return team.work;

internals.Empty = function () {
internals.chain = function (sources) {
Stream.Readable.call(this);
};
Hoek.inherits(internals.Empty, Stream.Readable);
internals.Empty.prototype._read = function (/* size */) {
this.push(null);
};
internals.cache = function (response) {
const request = response.request;
if (response.headers['cache-control']) {
return;
}
const policy = request.route.settings.cache &&
request._route._cache &&
(request.route.settings.cache._statuses[response.statusCode] || (response.statusCode === 304 && request.route.settings.cache._statuses['200']));
if (policy ||
response.settings.ttl) {
const ttl = (response.settings.ttl !== null ? response.settings.ttl : request._route._cache.ttl());
const privacy = (request.auth.isAuthenticated || response.headers['set-cookie'] ? 'private' : request.route.settings.cache.privacy || 'default');
response._header('cache-control', 'max-age=' + Math.floor(ttl / 1000) + ', must-revalidate' + (privacy !== 'default' ? ', ' + privacy : ''));
}
else if (request.route.settings.cache) {
response._header('cache-control', request.route.settings.cache.otherwise);
}
};
internals.content = function (response, postMarshal) {
let type = response.headers['content-type'];
if (!type) {
if (response._contentType) {
const charset = (response.settings.charset && response._contentType !== 'application/octet-stream' ? '; charset=' + response.settings.charset : '');
response.type(response._contentType + charset);
let from = sources[0];
for (let i = 1; i < sources.length; ++i) {
const to = sources[i];
if (to) {
from.once('error', (err) => to.emit('error', err));
from = from.pipe(to);
}
}
else {
type = type.trim();
if ((!response._contentType || !postMarshal) &&
response.settings.charset &&
type.match(/^(?:text\/)|(?:application\/(?:json)|(?:javascript))/)) {
if (!type.match(/; *charset=/)) {
const semi = (type[type.length - 1] === ';');
response.type(type + (semi ? ' ' : '; ') + 'charset=' + (response.settings.charset));
}
}
}
return from;
};
internals.state = async function (response) {
const request = response.request;
const names = {};
const states = [];
const requestStates = Object.keys(request._states);
for (let i = 0; i < requestStates.length; ++i) {
const stateName = requestStates[i];
names[stateName] = true;
states.push(request._states[stateName]);
}
const keys = Object.keys(request.server.states.cookies);
for (let i = 0; i < keys.length; ++i) {
const name = keys[i];
const autoValue = request.server.states.cookies[name].autoValue;
if (!autoValue || names[name]) {
continue;
}
names[name] = true;
if (typeof autoValue !== 'function') {
states.push({ name, value: autoValue });
continue;
}
try {
const value = await autoValue(request);
states.push({ name, value });
}
catch (err) {
throw Boom.boomify(err);
}
}
if (!states.length) {
return;
}
let header = await request.server.states.format(states);
const existing = response.headers['set-cookie'];
if (existing) {
header = (Array.isArray(existing) ? existing : [existing]).concat(header);
}
response._header('set-cookie', header);
};
internals.unmodified = function (response) {
const request = response.request;
// Set headers from reply.entity()
if (request._entity.etag &&
!response.headers.etag) {
response.etag(request._entity.etag, { vary: request._entity.vary });
}
if (request._entity.modified &&
!response.headers['last-modified']) {
response.header('last-modified', request._entity.modified);
}
if (response.statusCode === 304) {
return;
}
const entity = {
etag: response.headers.etag,
vary: response.settings.varyEtag,
modified: response.headers['last-modified']
};
if (Response.unmodified(request, entity)) {
response.code(304);
}
};

@@ -146,3 +146,3 @@ 'use strict';

return request.server._replier.execute(request.route.settings.validate.failAction, request, { realm: request.route.realm, args: [source, error] });
return request.server._responder.execute(request.route.settings.validate.failAction, request, { realm: request.route.realm, args: [source, error] });
};

@@ -238,4 +238,4 @@

return request.server._replier.execute(request.route.settings.response.failAction, request, { realm: request.route.realm, args: [err] });
return request.server._responder.execute(request.route.settings.response.failAction, request, { realm: request.route.realm, args: [err] });
}
};

@@ -5,3 +5,3 @@ {

"homepage": "http://hapijs.com",
"version": "17.0.0-rc1",
"version": "17.0.0-rc2",
"repository": {

@@ -8,0 +8,0 @@ "type": "git",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc