Skip to content

Commit

Permalink
feat: Run beforeRequest hooks before templating request params
Browse files Browse the repository at this point in the history
This change allows beforeRequest hooks to create context vars,
which will then be used in the templates of the current request
as expected.
  • Loading branch information
hassy committed May 6, 2017
1 parent 5ececa4 commit 405b78e
Showing 1 changed file with 65 additions and 66 deletions.
131 changes: 65 additions & 66 deletions lib/engine_http.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
return callback(err, context);
}

let url = maybePrependBase(template(params.url || params.uri, context), config);
delete params.uri;
let tls = config.tls || {};
let timeout = config.timeout || _.get(config, 'http.timeout') || 120;

Expand All @@ -162,9 +160,10 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
}
}

// Run beforeRequest processors (scenario-level ones too)
let requestParams = _.cloneDeep(params);
requestParams = _.extend(requestParams, {
url: url,
url: maybePrependBase(params.url || params.uri, config), // *NOT* templating here
method: method,
headers: {
},
Expand All @@ -173,69 +172,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
});
requestParams = _.extend(requestParams, tls);

if (params.json) {
requestParams.json = template(params.json, context);
}

if (params.body) {
requestParams.body = template(params.body, context);
}

if (params.form) {
requestParams.form = _.reduce(
requestParams.form,
function (acc, v, k) {
acc[k] = template(v, context);
return acc;
},
{});
}

// Assign default headers then overwrite as needed
let defaultHeaders = lowcaseKeys(
(config.defaults && config.defaults.headers) ?
config.defaults.headers : {'user-agent': USER_AGENT});
requestParams.headers = _.extend(defaultHeaders,
lowcaseKeys(params.headers));
let headers = _.reduce(requestParams.headers,
function(acc, v, k) {
acc[k] = template(v, context);
return acc;
}, {});
requestParams.headers = headers;

let defaultCookie = config.defaults ? config.defaults.cookie || {} : {};
let cookie = _.reduce(
params.cookie,
function(acc, v, k) {
acc[k] = v;
return acc;
},
defaultCookie);

if (cookie) {
_.each(cookie, function(v, k) {
context._jar.setCookie(k + '=' + template(v, context), url);
});
}

if (typeof requestParams.auth === 'object') {
requestParams.auth.user = template(requestParams.auth.user, context);
requestParams.auth.pass = template(requestParams.auth.pass, context);
}

if (config.http2) {
requestParams.http2 = true;
} else {
if (!self.pool) {
requestParams.agent = context._agent;
} else {

requestParams.pool = self.pool;
}
}

// Run beforeRequest processors (scenario-level ones too)
let functionNames = _.concat(opts.beforeRequest || [], params.beforeRequest || []);

async.eachSeries(
Expand All @@ -259,6 +195,69 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
return callback(err, context);
}

// Assemble the new request params
if (params.json) {
requestParams.json = template(params.json, context);
}

if (params.body) {
requestParams.body = template(params.body, context);
}

if (params.form) {
requestParams.form = _.reduce(
requestParams.form,
function (acc, v, k) {
acc[k] = template(v, context);
return acc;
},
{});
}

// Assign default headers then overwrite as needed
let defaultHeaders = lowcaseKeys(
(config.defaults && config.defaults.headers) ?
config.defaults.headers : {'user-agent': USER_AGENT});
requestParams.headers = _.extend(defaultHeaders,
lowcaseKeys(params.headers));
let headers = _.reduce(requestParams.headers,
function(acc, v, k) {
acc[k] = template(v, context);
return acc;
}, {});
requestParams.headers = headers;

let defaultCookie = config.defaults ? config.defaults.cookie || {} : {};
let cookie = _.reduce(
params.cookie,
function(acc, v, k) {
acc[k] = v;
return acc;
},
defaultCookie);

if (cookie) {
_.each(cookie, function(v, k) {
context._jar.setCookie(k + '=' + template(v, context), url);
});
}

if (typeof requestParams.auth === 'object') {
requestParams.auth.user = template(requestParams.auth.user, context);
requestParams.auth.pass = template(requestParams.auth.pass, context);
}

if (config.http2) {
requestParams.http2 = true;
} else {
if (!self.pool) {
requestParams.agent = context._agent;
} else {

requestParams.pool = self.pool;
}
}

let url = maybePrependBase(template(requestParams.uri || requestParams.url, context), config);

if (requestParams.uri) {
Expand Down

1 comment on commit 405b78e

@erikerikson
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Hassy. This change broke plugins such as artillery-plugin-aws-sigv4 which expects the template logic to have replaced variables so that it can sign the request using the final url.

Are there affordances for running code after template execution? If not, ideas?

Ref: Nordstrom/artillery-plugin-aws-sigv4#13

Please sign in to comment.