Skip to content

Commit

Permalink
fix(logo-favicon): favicon.ico with valid content-type
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Feb 25, 2024
1 parent 0ccefde commit 4c7007d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/metascraper-logo-favicon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"reachable-url": "~1.8.0"
},
"devDependencies": {
"async-listen": "latest",
"ava": "5"
},
"engines": {
Expand Down
14 changes: 11 additions & 3 deletions packages/metascraper-logo-favicon/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,18 @@ pickBiggerSize.sortBySize = collection =>
const favicon = async (url, { gotOpts } = {}) => {
const faviconUrl = logo('/favicon.ico', { url })
if (!faviconUrl) return undefined

const response = await reachableUrl(faviconUrl, gotOpts)
return reachableUrl.isReachable(response) &&
response.headers['content-type']?.startsWith('image')
? faviconUrl
const contentType = response.headers['content-type']

const isValidContenType =
contentType &&
['image/vnd.microsoft.icon', 'image/x-icon'].some(ct =>
contentType.includes(ct)
)

return isValidContenType && reachableUrl.isReachable(response)
? response.url
: undefined
}

Expand Down
44 changes: 43 additions & 1 deletion packages/metascraper-logo-favicon/test/favicon.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,54 @@ const test = require('ava')

const { favicon } = require('..')

const { runServer } = require('./helpers')

test('return undefined if favicon is not reachable', async t => {
const url = 'https://idontexist.lol'
t.is(await favicon(url), undefined)
})

test("with { contentType: 'image/vnd.microsoft.icon' }", async t => {
test("don't resolve favicon.ico with no content-type", async t => {
const server = await runServer(
t,
async ({ res }) => {
res.end('<svg></svg>')
},
{ host: '0.0.0.0', port: 0 }
)
t.is(await favicon(server), undefined)
})

test("don't resolve favicon.ico with no valid content-type", async t => {
const server = await runServer(
t,
async ({ res }) => {
res.setHeader('content-type', 'image/svg+xml; charset=utf-8')
res.end('<svg></svg>')
},
{ host: '0.0.0.0', port: 0 }
)
t.is(await favicon(server), undefined)
})

test("favicon.ico with 'image/vnd.microsoft.icon' content-type", async t => {
const url = 'https://microlink.io/'
t.is(await favicon(url), 'https://microlink.io/favicon.ico')
})

test("favicon.ico with 'image/x-icon' content-type", async t => {
const url = 'https://2miners.com/'
t.is(await favicon(url), 'https://2miners.com/favicon.ico')
})

test('handle redirects', async t => {
const server = await runServer(
t,
async ({ res }) => {
res.writeHead(301, { Location: 'https://microlink.io/favicon.ico' })
res.end()
},
{ host: '0.0.0.0', port: 0 }
)
t.is(await favicon(server), 'https://microlink.io/favicon.ico')
})
24 changes: 24 additions & 0 deletions packages/metascraper-logo-favicon/test/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'

const { default: listen } = require('async-listen')
const { createServer } = require('http')

const closeServer = server =>
require('util').promisify(server.close.bind(server))()

const runServer = async (t, handler, opts) => {
const server = createServer(async (req, res) => {
try {
await handler({ req, res })
} catch (error) {
console.error(error)
res.statusCode = 500
res.end()
}
})
const url = await listen(server, opts)
t.teardown(() => closeServer(server))
return url
}

module.exports = { runServer }

0 comments on commit 4c7007d

Please sign in to comment.