Skip to content

Commit c173f3c

Browse files
committed
fix: ensure fallback url is reachable
1 parent 32bf91e commit c173f3c

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"@microlink/mql": "~0.12.2",
9292
"@microlink/ping-url": "~1.4.11",
9393
"@microlink/ua": "~1.2.0",
94+
"async-memoize-one": "~1.1.6",
9495
"browserless": "~10.2.4",
9596
"cacheable-lookup": "~6.1.0",
9697
"cacheable-response": "~2.8.10",
@@ -110,7 +111,6 @@
110111
"is-email-like": "~1.0.0",
111112
"is-url-http": "~2.3.7",
112113
"lodash": "~4.17.21",
113-
"memoize-one": "~6.0.0",
114114
"ms": "~2.1.3",
115115
"on-finished": "~2.4.1",
116116
"p-any": "~3.0.0",

src/avatar/resolve.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use strict'
22

33
const debug = require('debug-logfmt')('unavatar:resolve')
4+
const reachableUrl = require('../util/reachable-url')
45
const isAbsoluteUrl = require('is-absolute-url')
6+
const memoizeOne = require('async-memoize-one')
57
const { getTtl } = require('../send/cache')
6-
const memoizeOne = require('memoize-one')
78
const isUrlHttp = require('is-url-http')
89
const pTimeout = require('p-timeout')
910
const pReflect = require('p-reflect')
@@ -44,16 +45,18 @@ const optimizeUrl = async (url, query) => {
4445
}).toString()}`
4546
}
4647

47-
const getDefaultFallbackUrl = memoizeOne(
48-
({ protocol, host }) => `${protocol}://${host}/fallback.png`
49-
)
48+
const getDefaultFallbackUrl = ({ protocol, host }) =>
49+
this.url || (this.url = `${protocol}://${host}/fallback.png`)
5050

51-
const getFallbackUrl = memoizeOne(({ query, protocol, host }) => {
51+
const getFallbackUrl = memoizeOne(async ({ query, protocol, host }) => {
5252
const { fallback } = query
5353
if (fallback === false) return null
54-
55-
return isUrlHttp(fallback) && isAbsoluteUrl(fallback)
56-
? fallback
54+
if (!isUrlHttp(fallback) || !isAbsoluteUrl(fallback)) {
55+
return getDefaultFallbackUrl({ protocol, host })
56+
}
57+
const { statusCode, url } = await reachableUrl(fallback)
58+
return reachableUrl.isReachable({ statusCode })
59+
? url
5760
: getDefaultFallbackUrl({ protocol, host })
5861
})
5962

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

7679
if (value === undefined) {
77-
const data = getFallbackUrl({ query, protocol, host })
80+
const data = await getFallbackUrl({ query, protocol, host })
7881
value = data ? { type: 'url', data } : null
7982
}
8083

src/server.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ server.listen(PORT, () => {
2121
address: API_URL
2222
})
2323
})
24+
25+
process.on('uncaughtException', error => {
26+
debug.error('uncaughtException', {
27+
requestUrl: error.response?.requestUrl
28+
})
29+
})

test/query-parameters.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@ test('fallback', async t => {
3636
t.is(headers['content-type'], 'application/json; charset=utf-8')
3737
})
3838

39+
test('fallback # use default value if fallback provided is not reachable', async t => {
40+
const serverUrl = await runServer(t)
41+
42+
const { headers, body } = await got(
43+
'github/__notexistprofile__?fallback=https://nexmoe.com/thisis404.png&json',
44+
{
45+
prefixUrl: serverUrl,
46+
responseType: 'json'
47+
}
48+
)
49+
50+
t.is(body.url, `${serverUrl.toString()}fallback.png`)
51+
t.is(headers['content-type'], 'application/json; charset=utf-8')
52+
})
53+
3954
test('ttl', t => {
4055
t.is(getTtl(), CACHE_TTL)
4156
t.is(getTtl(null), CACHE_TTL)

0 commit comments

Comments
 (0)