Skip to content

Commit

Permalink
fix: ensure fallback url is reachable
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Jan 15, 2024
1 parent 32bf91e commit c173f3c
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"@microlink/mql": "~0.12.2",
"@microlink/ping-url": "~1.4.11",
"@microlink/ua": "~1.2.0",
"async-memoize-one": "~1.1.6",
"browserless": "~10.2.4",
"cacheable-lookup": "~6.1.0",
"cacheable-response": "~2.8.10",
Expand All @@ -110,7 +111,6 @@
"is-email-like": "~1.0.0",
"is-url-http": "~2.3.7",
"lodash": "~4.17.21",
"memoize-one": "~6.0.0",
"ms": "~2.1.3",
"on-finished": "~2.4.1",
"p-any": "~3.0.0",
Expand Down
21 changes: 12 additions & 9 deletions src/avatar/resolve.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use strict'

const debug = require('debug-logfmt')('unavatar:resolve')
const reachableUrl = require('../util/reachable-url')
const isAbsoluteUrl = require('is-absolute-url')
const memoizeOne = require('async-memoize-one')
const { getTtl } = require('../send/cache')
const memoizeOne = require('memoize-one')
const isUrlHttp = require('is-url-http')
const pTimeout = require('p-timeout')
const pReflect = require('p-reflect')
Expand Down Expand Up @@ -44,16 +45,18 @@ const optimizeUrl = async (url, query) => {
}).toString()}`
}

const getDefaultFallbackUrl = memoizeOne(
({ protocol, host }) => `${protocol}://${host}/fallback.png`
)
const getDefaultFallbackUrl = ({ protocol, host }) =>
this.url || (this.url = `${protocol}://${host}/fallback.png`)

const getFallbackUrl = memoizeOne(({ query, protocol, host }) => {
const getFallbackUrl = memoizeOne(async ({ query, protocol, host }) => {
const { fallback } = query
if (fallback === false) return null

return isUrlHttp(fallback) && isAbsoluteUrl(fallback)
? fallback
if (!isUrlHttp(fallback) || !isAbsoluteUrl(fallback)) {
return getDefaultFallbackUrl({ protocol, host })
}
const { statusCode, url } = await reachableUrl(fallback)
return reachableUrl.isReachable({ statusCode })
? url
: getDefaultFallbackUrl({ protocol, host })
})

Expand All @@ -74,7 +77,7 @@ module.exports = fn => async (req, res) => {
}

if (value === undefined) {
const data = getFallbackUrl({ query, protocol, host })
const data = await getFallbackUrl({ query, protocol, host })
value = data ? { type: 'url', data } : null
}

Expand Down
6 changes: 6 additions & 0 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ server.listen(PORT, () => {
address: API_URL
})
})

process.on('uncaughtException', error => {
debug.error('uncaughtException', {
requestUrl: error.response?.requestUrl
})
})
15 changes: 15 additions & 0 deletions test/query-parameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ test('fallback', async t => {
t.is(headers['content-type'], 'application/json; charset=utf-8')
})

test('fallback # use default value if fallback provided is not reachable', async t => {
const serverUrl = await runServer(t)

const { headers, body } = await got(
'github/__notexistprofile__?fallback=https://nexmoe.com/thisis404.png&json',
{
prefixUrl: serverUrl,
responseType: 'json'
}
)

t.is(body.url, `${serverUrl.toString()}fallback.png`)
t.is(headers['content-type'], 'application/json; charset=utf-8')
})

test('ttl', t => {
t.is(getTtl(), CACHE_TTL)
t.is(getTtl(null), CACHE_TTL)
Expand Down

0 comments on commit c173f3c

Please sign in to comment.