Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3f4eef1
simplified header rules
kathmbeck Oct 18, 2023
6bf8782
lint
kathmbeck Oct 18, 2023
342f1aa
Merge branch 'master' into adapter-header-rules
kathmbeck Oct 18, 2023
20cc896
lint
kathmbeck Oct 18, 2023
b58b9f7
update test/snapshot
kathmbeck Oct 19, 2023
45b6f5e
update snapshot
kathmbeck Oct 19, 2023
66859d6
Merge branch 'master' into adapter-header-rules
kathmbeck Oct 19, 2023
5254cb8
add snapshot for headerRoutes
kathmbeck Oct 20, 2023
1db7da7
Merge branch 'master' into adapter-header-rules
kathmbeck Oct 20, 2023
c1d54ae
adapter use headerRoutes
kathmbeck Oct 20, 2023
feee869
export type
kathmbeck Oct 20, 2023
cbbe1da
Merge branch 'adapter-header-rules' into use-header-routes
kathmbeck Oct 20, 2023
333e960
first pass at headers tests
kathmbeck Oct 24, 2023
c69f76a
Merge branch 'master' into use-header-routes
kathmbeck Oct 24, 2023
5627ed6
Merge branch 'use-header-routes' of https://github.com/gatsbyjs/gatsb…
kathmbeck Oct 24, 2023
d08a337
merge conflict fix
kathmbeck Oct 24, 2023
0beb1ab
lint error
kathmbeck Oct 24, 2023
d3555e6
remove accidental nesting
kathmbeck Oct 24, 2023
763cd13
tests
kathmbeck Oct 26, 2023
9578dec
tests
kathmbeck Oct 26, 2023
fe00ca5
static assets todo
kathmbeck Oct 26, 2023
c1a9ffd
example of permanent caching header assertion
pieh Oct 30, 2023
90694c1
ensure getServerData header has priority over config header for SSR p…
pieh Oct 30, 2023
5063e03
normalize header values before assertions
pieh Oct 30, 2023
6257dd8
add page- and app-data header checks
pieh Oct 30, 2023
58d94cb
tmp: skip deleting deploys for easier iteration
pieh Oct 30, 2023
e05986d
refactor test a bit so it's easier to assert same thing in multiple t…
pieh Oct 30, 2023
0353fe9
add slice-data headers check
pieh Oct 30, 2023
150e4e9
add static query result header test
pieh Oct 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions e2e-tests/adapters/cypress/e2e/headers.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { title } from "../../constants"

describe("Headers", () => {
function checkHeaders(routeAlias, expectedHeaders) {
cy.wait(routeAlias).then(interception => {
Object.keys(expectedHeaders).forEach(headerKey => {
expect(interception.response.headers[headerKey]).to.eq(
expectedHeaders[headerKey]
)
})
})
}

const defaultHeaders = {
"x-xss-protection": "1; mode=block",
"x-content-type-options": "nosniff",
"referrer-policy": "same-origin",
"x-frame-options": "DENY",
}

it("should contain correct headers for index page", () => {
cy.intercept("/").as("index")
cy.visit("/")

checkHeaders("@index", {
...defaultHeaders,
"x-custom-header": "my custom header value",
})
})

// it("should contain correct headers for static assets", () => {
// @todo
// })

it("should contain correct headers for ssr page", () => {
cy.intercept("routes/ssr/static").as("ssr")
cy.visit("routes/ssr/static")

checkHeaders("@ssr", {
...defaultHeaders,
"x-ssr-header": "my custom header value from config",
})
})

it("should contain correct headers for dsg page", () => {
cy.intercept("routes/dsg/static").as("dsg")
cy.visit("routes/dsg/static")

checkHeaders("@dsg", {
...defaultHeaders,
"x-dsg-header": "my custom header value",
})
})
})
34 changes: 21 additions & 13 deletions e2e-tests/adapters/debug-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inspect } from "util"
import type { AdapterInit } from "gatsby"

const createTestingAdapter: AdapterInit = (adapterOptions) => {
const createTestingAdapter: AdapterInit = adapterOptions => {
return {
name: `gatsby-adapter-debug`,
cache: {
Expand All @@ -10,28 +10,36 @@ const createTestingAdapter: AdapterInit = (adapterOptions) => {
},
store({ directories, reporter }) {
reporter.info(`[gatsby-adapter-debug] cache.store() ${directories}`)
}
},
},
adapt({
routesManifest,
headerRoutes,
functionsManifest,
pathPrefix,
trailingSlash,
reporter,
}) {
reporter.info(`[gatsby-adapter-debug] adapt()`)

console.log(`[gatsby-adapter-debug] adapt()`, inspect({
routesManifest,
functionsManifest,
pathPrefix,
trailingSlash,
}, {
depth: Infinity,
colors: true
}))
}
console.log(
`[gatsby-adapter-debug] adapt()`,
inspect(
{
routesManifest,
headerRoutes,
functionsManifest,
pathPrefix,
trailingSlash,
},
{
depth: Infinity,
colors: true,
}
)
)
},
}
}

export default createTestingAdapter
export default createTestingAdapter
36 changes: 35 additions & 1 deletion e2e-tests/adapters/gatsby-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import debugAdapter from "./debug-adapter"
import { siteDescription, title } from "./constants"

const shouldUseDebugAdapter = process.env.USE_DEBUG_ADAPTER ?? false
const trailingSlash = (process.env.TRAILING_SLASH || `never`) as GatsbyConfig["trailingSlash"]
const trailingSlash = (process.env.TRAILING_SLASH ||
`never`) as GatsbyConfig["trailingSlash"]

let configOverrides: GatsbyConfig = {}

Expand All @@ -21,6 +22,39 @@ const config: GatsbyConfig = {
},
trailingSlash,
plugins: [],
headers: [
{
source: `/*`,
headers: [
{
key: "x-custom-header",
value: "my custom header value",
},
],
},
{
source: `routes/ssr/*`,
headers: [
{
key: "x-ssr-header",
value: "my custom header value from config",
},
{
key: "x-ssr-header-overwrite",
value: "my custom header value from config",
},
],
},
{
source: `routes/dsg/*`,
headers: [
{
key: "x-dsg-header",
value: "my custom header value",
},
],
},
],
...configOverrides,
}

Expand Down
9 changes: 7 additions & 2 deletions packages/gatsby-adapter-netlify/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,14 @@ const createNetlifyAdapter: AdapterInit<INetlifyAdapterOptions> = options => {
}
},
},
async adapt({ routesManifest, functionsManifest }): Promise<void> {
async adapt({
routesManifest,
functionsManifest,
headerRoutes,
}): Promise<void> {
const { lambdasThatUseCaching } = await handleRoutesManifest(
routesManifest
routesManifest,
headerRoutes
)

// functions handling
Expand Down
42 changes: 30 additions & 12 deletions packages/gatsby-adapter-netlify/src/route-handler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RoutesManifest } from "gatsby"
import type { RoutesManifest, HeaderRoutes } from "gatsby"
import { tmpdir } from "os"
import { Transform } from "stream"
import { join, basename } from "path"
Expand Down Expand Up @@ -130,7 +130,17 @@ export async function injectEntries(
await fs.move(tmpFile, fileName)
}

export function processRoutesManifest(routesManifest: RoutesManifest): {
function buildHeaderString(path, headers): string {
return `${encodeURI(path)}\n${headers.reduce((acc, curr) => {
acc += ` ${curr.key}: ${curr.value}\n`
return acc
}, ``)}`
}

export function processRoutesManifest(
routesManifest: RoutesManifest,
headerRoutes: HeaderRoutes
): {
redirects: string
headers: string
lambdasThatUseCaching: Map<string, string>
Expand Down Expand Up @@ -212,25 +222,33 @@ export function processRoutesManifest(routesManifest: RoutesManifest): {
)} 200\n`
}

_headers += `${encodeURI(fromPath)}\n${route.headers.reduce(
(acc, curr) => {
acc += ` ${curr.key}: ${curr.value}\n`
return acc
},
``
)}`
if (!headerRoutes) {
// don't generate _headers from routesManifest if headerRoutes are provided
_headers += buildHeaderString(route.path, route.headers)
}
}

if (headerRoutes) {
_headers = headerRoutes.reduce((acc, curr) => {
acc += buildHeaderString(curr.path, curr.headers)
return acc
}, ``)
}
}
return { redirects: _redirects, headers: _headers, lambdasThatUseCaching }
}

export async function handleRoutesManifest(
routesManifest: RoutesManifest
routesManifest: RoutesManifest,
headerRoutes: HeaderRoutes
): Promise<{
lambdasThatUseCaching: Map<string, string>
}> {
const { redirects, headers, lambdasThatUseCaching } =
processRoutesManifest(routesManifest)
const { redirects, headers, lambdasThatUseCaching } = processRoutesManifest(
routesManifest,
headerRoutes
)

await injectEntries(`public/_redirects`, redirects)
await injectEntries(`public/_headers`, headers)

Expand Down