Skip to content

Commit

Permalink
fix: html urls should not be absolute (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidTanner authored Oct 17, 2024
1 parent 030970d commit e32e32c
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 13 deletions.
6 changes: 4 additions & 2 deletions lib/index-html.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use strict'

function indexHtml (opts) {
return (hasTrailingSlash) => {
const prefix = hasTrailingSlash ? `.${opts.staticPrefix}` : `${opts.prefix}${opts.staticPrefix}`
const hasLeadingSlash = /^\//.test(opts.prefix)
return (url) => {
const hasTrailingSlash = /\/$/.test(url)
const prefix = hasTrailingSlash ? `.${opts.staticPrefix}` : `${hasLeadingSlash ? '.' : ''}${opts.prefix}${opts.staticPrefix}`
return `<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
Expand Down
3 changes: 1 addition & 2 deletions lib/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,9 @@ function fastifySwagger (fastify, opts, done) {
schema: { hide: true },
...hooks,
handler: (req, reply) => {
const hasTrailingSlash = /\/$/.test(req.url)
reply
.header('content-type', 'text/html; charset=utf-8')
.send(indexHtmlContent(hasTrailingSlash)) // trailing slash alters the relative urls generated in the html
.send(indexHtmlContent(req.url)) // trailing slash alters the relative urls generated in the html
}
})

Expand Down
130 changes: 121 additions & 9 deletions test/route.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ test('should return empty log level of route /documentation', async (t) => {
})

test('/documentation should display index html with correct asset urls', async (t) => {
t.plan(4)
t.plan(6)
const fastify = Fastify()
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] } })
Expand All @@ -548,10 +548,122 @@ test('/documentation should display index html with correct asset urls', async (
url: '/documentation'
})

t.equal(res.payload.includes('href="/documentation/static/index.css"'), true)
t.equal(res.payload.includes('src="/documentation/static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="/documentation/index.css"'), false)
t.equal(res.payload.includes('src="/documentation/theme/theme-js.js"'), false)
t.equal(res.payload.includes('href="./documentation/static/index.css"'), true)
t.equal(res.payload.includes('src="./documentation/static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="./documentation/index.css"'), false)
t.equal(res.payload.includes('src="./documentation/theme/theme-js.js"'), false)

let cssRes = await fastify.inject({
method: 'GET',
url: '/documentation/static/index.css'
})
t.equal(cssRes.statusCode, 200)
cssRes = await fastify.inject({
method: 'GET',
url: './documentation/static/index.css'
})
t.equal(cssRes.statusCode, 200)
})

/**
* This emulates when the server is inside an NGINX application that routes by path
*/
test('/documentation should display index html with correct asset urls when nested', async (t) => {
t.plan(5)
const fastify = Fastify()
await fastify.register(
async () => {
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] } })
},
{
prefix: '/swagger-app'
}
)

const res = await fastify.inject({
method: 'GET',
url: '/swagger-app/documentation'
})

t.equal(res.payload.includes('href="./documentation/static/index.css"'), true)
t.equal(res.payload.includes('src="./documentation/static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="./documentation/index.css"'), false)
t.equal(res.payload.includes('src="./documentation/theme/theme-js.js"'), false)

const cssRes = await fastify.inject({
method: 'GET',
url: '/swagger-app/documentation/static/index.css'
})
t.equal(cssRes.statusCode, 200)
})

test('/documentation/ should display index html with correct asset urls', async (t) => {
t.plan(4)
const fastify = Fastify()
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] } })

const res = await fastify.inject({
method: 'GET',
url: '/documentation/'
})

t.equal(res.payload.includes('href="./static/index.css"'), true)
t.equal(res.payload.includes('src="./static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="./index.css"'), false)
t.equal(res.payload.includes('src="./theme/theme-js.js"'), false)
})

test('/docs should display index html with correct asset urls when documentation prefix is set', async (t) => {
t.plan(4)
const fastify = Fastify()
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] }, routePrefix: '/docs' })

const res = await fastify.inject({
method: 'GET',
url: '/docs'
})

t.equal(res.payload.includes('href="./docs/static/index.css"'), true)
t.equal(res.payload.includes('src="./docs/static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="./docs/index.css"'), false)
t.equal(res.payload.includes('src="./docs/theme/theme-js.js"'), false)
})

test('/docs should display index html with correct asset urls when documentation prefix is set with no leading slash', async (t) => {
t.plan(4)
const fastify = Fastify()
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] }, routePrefix: 'docs' })

const res = await fastify.inject({
method: 'GET',
url: '/docs'
})

t.equal(res.payload.includes('href="docs/static/index.css"'), true)
t.equal(res.payload.includes('src="docs/static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="docs/index.css"'), false)
t.equal(res.payload.includes('src="docs/theme/theme-js.js"'), false)
})

test('/docs/ should display index html with correct asset urls when documentation prefix is set', async (t) => {
t.plan(4)
const fastify = Fastify()
await fastify.register(fastifySwagger, swaggerOption)
await fastify.register(fastifySwaggerUi, { theme: { js: [{ filename: 'theme-js.js' }] }, routePrefix: '/docs' })

const res = await fastify.inject({
method: 'GET',
url: '/docs/'
})

t.equal(res.payload.includes('href="./static/index.css"'), true)
t.equal(res.payload.includes('src="./static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="./index.css"'), false)
t.equal(res.payload.includes('src="./theme/theme-js.js"'), false)
})

test('/documentation/ should display index html with correct asset urls', async (t) => {
Expand Down Expand Up @@ -582,10 +694,10 @@ test('/docs should display index html with correct asset urls when documentation
url: '/docs'
})

t.equal(res.payload.includes('href="/docs/static/index.css"'), true)
t.equal(res.payload.includes('src="/docs/static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="/docs/index.css"'), false)
t.equal(res.payload.includes('src="/docs/theme/theme-js.js"'), false)
t.equal(res.payload.includes('href="./docs/static/index.css"'), true)
t.equal(res.payload.includes('src="./docs/static/theme/theme-js.js"'), true)
t.equal(res.payload.includes('href="./docs/index.css"'), false)
t.equal(res.payload.includes('src="./docs/theme/theme-js.js"'), false)
})

test('/docs/ should display index html with correct asset urls when documentation prefix is set', async (t) => {
Expand Down

0 comments on commit e32e32c

Please sign in to comment.