Skip to content

Commit d071712

Browse files
authored
feat: add support for /_gatsby/file/* redirects (#305)
1 parent 988d9a2 commit d071712

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

plugin/src/helpers/functions.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,18 @@ export const setupImageCdn = async ({
7878
join(constants.INTERNAL_FUNCTIONS_SRC, '_ipx.ts'),
7979
)
8080

81-
netlifyConfig.redirects.push({
82-
from: '/_gatsby/image/*',
83-
to: '/.netlify/builders/_ipx',
84-
status: 200,
85-
})
81+
netlifyConfig.redirects.push(
82+
{
83+
from: '/_gatsby/image/*',
84+
to: '/.netlify/builders/_ipx',
85+
status: 200,
86+
},
87+
{
88+
from: '/_gatsby/file/*',
89+
to: '/.netlify/functions/_ipx',
90+
status: 200,
91+
},
92+
)
8693
}
8794

8895
export const deleteFunctions = async ({

plugin/src/templates/ipx.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,47 @@
1+
import { Buffer } from 'buffer'
2+
3+
import { Handler, HandlerResponse } from '@netlify/functions'
14
import { createIPXHandler } from '@netlify/ipx'
25

3-
export const handler = createIPXHandler({
6+
const ipxHandler = createIPXHandler({
47
propsEncoding: 'base64',
58
basePath: '/_gatsby/image/',
69
bypassDomainCheck: true,
710
})
11+
12+
// eslint-disable-next-line require-await
13+
export const handler: Handler = async (event, ...rest) => {
14+
const { pathname, host } = new URL(event.rawUrl)
15+
16+
const [, , type, encodedUrl] = pathname.split('/')
17+
18+
if (type === 'image') {
19+
return ipxHandler(event, ...rest) as Promise<HandlerResponse>
20+
}
21+
22+
try {
23+
const urlString = Buffer.from(encodedUrl, 'base64').toString('utf8')
24+
// Validate it by parsing it
25+
const url = new URL(urlString)
26+
if (url.host === host) {
27+
return {
28+
statusCode: 400,
29+
body: 'File cannot be served from the same host as the original request',
30+
}
31+
}
32+
console.log(`Redirecting to ${urlString}`)
33+
return {
34+
statusCode: 301,
35+
headers: {
36+
Location: url.toString(),
37+
},
38+
body: '',
39+
}
40+
} catch (error) {
41+
console.error(error)
42+
return {
43+
statusCode: 400,
44+
body: 'Invalid request',
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)