Skip to content

Commit

Permalink
Add support for environments with proxy servers
Browse files Browse the repository at this point in the history
Our AWS environments require all requests to go through a proxy server; without support, our requests would get stuck.

We tackled this same problem in [Replace existing proxy config with global-agent](DEFRA/sroc-charging-module-api#572) in the sroc-charging-module-api. In the Charging Module, we used [global-agent](https://github.com/gajus/global-agent). This intercepts all http/https requests and adds the proxy details to them. Perfect!

The problem is it was last updated more than a year ago, the build is marked as failing, test coverage is low, and issues and PR's seem to be going unanswered. Our other issue is it does not recognise the lowercase versions of standard proxy env vars (`http_proxy`, `https_proxy` and `no_proxy`). It's a shame because it works seamlessly in the background.

The folks behind the request package we do use, [Got](https://github.com/sindresorhus/got), recommend a couple. We liked [hpagent](https://github.com/delvedor/hpagent/). The example was simple, it's being regularly updated, supports [keep-alive connections](https://en.wikipedia.org/wiki/HTTP_persistent_connection), and even uses [standardjs](https://standardjs.com/)!

So, this change supports working behind a proxy using **hpagent**.
  • Loading branch information
Cruikshanks committed Dec 15, 2022
1 parent e58acf0 commit b86101d
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 1 deletion.
10 changes: 10 additions & 0 deletions app/lib/request.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* @module RequestLib
*/

const { HttpsProxyAgent } = require('hpagent')

const requestConfig = require('../../config/request.config.js')

async function get (url, additionalOptions = {}) {
Expand Down Expand Up @@ -48,6 +50,14 @@ async function _importGot () {
*/
function _requestOptions (additionalOptions) {
const defaultOptions = {
// This uses the spread operator and a logical AND short circuit evaluation to allow us to determine whether the
// following columns are added to the options or not. Thanks to https://stackoverflow.com/a/40560953/6117745 for
// this
...(requestConfig.httpProxy && {
agent: {
https: new HttpsProxyAgent({ proxy: requestConfig.httpProxy })
}
}),
// If we don't have this setting Got will throw its own HTTPError unless the result is 2xx or 3xx. That makes it
// impossible to see what the status code was because it doesn't get set on the response object Got provides when
// an error is thrown. With this set Got will treat a 404 in the same way it treats a 204.
Expand Down
3 changes: 2 additions & 1 deletion config/request.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict'

const config = {
timeout: parseInt(process.env.REQUEST_TIMEOUT) || 5000
timeout: parseInt(process.env.REQUEST_TIMEOUT) || 5000,
httpProxy: process.env.http_proxy || 'http:localhost:1100'
}

module.exports = config
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"got": "^12.5.3",
"govuk-frontend": "^4.4.0",
"hapi-pino": "^11.0.1",
"hpagent": "^1.2.0",
"knex": "^2.3.0",
"nunjucks": "^3.2.3",
"objection": "^3.0.1",
Expand Down

0 comments on commit b86101d

Please sign in to comment.