From bb7d13d2d969feaafbe5c75299c570962db53b39 Mon Sep 17 00:00:00 2001 From: Stefan Ollinger Date: Thu, 5 Oct 2023 17:46:12 +0200 Subject: [PATCH] Use axios interceptor to measure response time --- .../src/runner/run-single-request.js | 22 ++++++---- .../bruno-cli/src/utils/axios-instance.js | 40 +++++++++++++++++++ 2 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 packages/bruno-cli/src/utils/axios-instance.js diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js index e5c42392..7323d409 100644 --- a/packages/bruno-cli/src/runner/run-single-request.js +++ b/packages/bruno-cli/src/runner/run-single-request.js @@ -10,6 +10,7 @@ const interpolateVars = require('./interpolate-vars'); const { ScriptRuntime, TestRuntime, VarsRuntime, AssertRuntime } = require('@usebruno/js'); const { stripExtension } = require('../utils/filesystem'); const { getOptions } = require('../utils/bru'); +const { makeAxiosInstance } = require('../utils/axios-instance'); const runSingleRequest = async function ( filename, @@ -123,15 +124,23 @@ const runSingleRequest = async function ( } let response, responseTime; - const start = Date.now(); try { // run request - response = await axios(request); - responseTime = Date.now() - start; + const axiosInstance = makeAxiosInstance(); + + /** @type {import('axios').AxiosResponse} */ + response = await axiosInstance(request); + + // Prevents the duration on leaking to the actual result + responseTime = response.headers.get('request-duration'); + response.headers.delete('request-duration'); } catch (err) { if (err && err.response) { response = err.response; - responseTime = Date.now() - start; + + // Prevents the duration on leaking to the actual result + responseTime = response.headers.get('request-duration'); + response.headers.delete('request-duration'); } else { console.log(chalk.red(stripExtension(filename)) + chalk.dim(` (${err.message})`)); return { @@ -155,10 +164,7 @@ const runSingleRequest = async function ( } } - console.log( - chalk.green(stripExtension(filename)) + - chalk.dim(` (${response.status} ${response.statusText}) - ${responseTime} ms`) - ); + console.log(chalk.green(stripExtension(filename)) + chalk.dim(` (${response.status} ${response.statusText}) - ${responseTime} ms`)); // run post-response vars const postResponseVars = get(bruJson, 'request.vars.res'); diff --git a/packages/bruno-cli/src/utils/axios-instance.js b/packages/bruno-cli/src/utils/axios-instance.js new file mode 100644 index 00000000..f4810bec --- /dev/null +++ b/packages/bruno-cli/src/utils/axios-instance.js @@ -0,0 +1,40 @@ +const axios = require('axios'); + +/** + * Function that configures axios with timing interceptors + * Important to note here that the timings are not completely accurate. + * @see https://github.com/axios/axios/issues/695 + * @returns {import('axios').AxiosStatic} + */ +function makeAxiosInstance() { + /** @type {import('axios').AxiosStatic} */ + const instance = axios.create(); + + instance.interceptors.request.use((config) => { + config.headers['request-start-time'] = Date.now(); + return config; + }); + + instance.interceptors.response.use( + (response) => { + const end = Date.now(); + const start = response.config.headers['request-start-time']; + response.headers['request-duration'] = end - start; + return response; + }, + (error) => { + if (error.response) { + const end = Date.now(); + const start = error.config.headers['request-start-time']; + error.response.headers['request-duration'] = end - start; + } + return Promise.reject(error); + } + ); + + return instance; +} + +module.exports = { + makeAxiosInstance +};