Skip to content

Commit 87dbae8

Browse files
authored
fix: support accept header as per conformance tests (#940)
Enable accept header related conformance tests and update implementation to make them pass.
1 parent 54f86b6 commit 87dbae8

19 files changed

+350
-209
lines changed

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@
1919

2020
## About
2121

22-
This project demonstrates
23-
the use of [Helia](https://github.com/ipfs/helia) (IPFS implementation in JS)
24-
and the [`verified-fetch` library](https://github.com/ipfs/helia-verified-fetch)
22+
This project demonstrates the use of [Helia](https://github.com/ipfs/helia)
23+
(IPFS implementation in JS) and the [`verified-fetch` library](https://github.com/ipfs/helia-verified-fetch)
2524
([Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for IPFS)
2625
within a [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)
2726
to facilitate direct verified retrieval of content-addressed data.
@@ -41,7 +40,6 @@ tasks.
4140

4241
This project was brought to you by the [Shipyard](http://ipshipyard.com/) team.
4342

44-
4543
### Goals
4644

4745
The main goals of this project are:
@@ -65,7 +63,6 @@ The main goals of this project are:
6563
gaps, and improve quality of libraries, specifications, and interop tests.
6664

6765

68-
6966
### Feature Set
7067

7168
- 🚧 **WIP:** Web interface for adjusting routing and retrieval settings.

build.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,7 @@ if (watchRequested) {
429429
if (serveRequested) {
430430
const { port } = await ctx.serve({
431431
servedir: 'dist',
432-
port: 8345,
433-
host: 'localhost'
432+
port: 8345
434433
})
435434
console.info(`Listening on http://localhost:${port}`)
436435
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
"dev": "node dist-tsc/serve.js --load-fixtures",
2222
"prestart": "run-s build:binary",
2323
"start": "./service-worker-gateway",
24-
"start:frontend": "node build.js --watch --serve",
2524
"start:cloudflare": "npm run build && npx wrangler pages dev dist",
2625
"prestart:hosted": "run-s build:tsc",
2726
"test": "run-s test:iso 'test:node -- -b false'",
@@ -63,7 +62,7 @@
6362
"@helia/http": "^3.0.8",
6463
"@helia/interface": "^6.0.2",
6564
"@helia/routers": "^4.0.3",
66-
"@helia/verified-fetch": "^5.0.0",
65+
"@helia/verified-fetch": "^5.0.4",
6766
"@ipld/dag-cbor": "^9.2.5",
6867
"@ipld/dag-json": "^10.2.5",
6968
"@ipld/dag-pb": "^4.1.5",
@@ -119,9 +118,11 @@
119118
"fast-glob": "^3.3.3",
120119
"glob": "^13.0.0",
121120
"http-server": "^14.1.1",
121+
"ipfs-unixfs": "^12.0.0",
122122
"ipfs-unixfs-importer": "^16.0.1",
123123
"ipns": "^10.1.3",
124124
"it-all": "^3.0.7",
125+
"it-drain": "^3.0.10",
125126
"it-to-buffer": "^4.0.10",
126127
"kubo": "^0.39.0",
127128
"kubo-rpc-client": "^6.0.2",

serve.ts

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,17 @@
1010
* This file expects that `build:tsc` was ran first, and this will be handled
1111
* for you if ran via `npm run start`.
1212
*/
13+
import { existsSync, createReadStream } from 'node:fs'
14+
import { createServer, Server } from 'node:http'
15+
import { join, extname } from 'node:path'
1316
import { pathToFileURL } from 'node:url'
14-
import { logger } from '@libp2p/logger'
1517
import { execa } from 'execa'
1618
import { createKuboNode } from './test-e2e/fixtures/create-kubo-node.js'
1719
import { loadIpnsRecords } from './test-e2e/fixtures/load-ipns-records.js'
1820
import { downloadFixtures, getIpfsNsMap, loadCarFixtures } from './test-e2e/fixtures/load-kubo-fixtures.js'
1921
import { setupIpfsGateway } from './test-e2e/ipfs-gateway.js'
20-
import { createReverseProxy } from './test-e2e/reverse-proxy.js'
2122
import type { KuboNode } from 'ipfsd-ctl'
2223

23-
const log = logger('serve')
24-
2524
// if user passes "--load-fixtures" flag, load all the fixtures
2625
const args = process.argv.slice(2)
2726

@@ -34,14 +33,49 @@ async function loadFixtures (): Promise<{
3433
const controller = await createKuboNode(IPFS_NS_MAP)
3534
await controller.start()
3635

37-
await loadCarFixtures()
38-
await loadIpnsRecords(controller, log)
36+
await loadCarFixtures(controller)
37+
await loadIpnsRecords(controller)
3938

4039
return {
4140
controller
4241
}
4342
}
4443

44+
const MIME_TYPES: Record<string, string> = {
45+
'.js': 'text/javascript; charset=utf8',
46+
'.png': 'image/png',
47+
'.map': 'text/plain',
48+
'.css': 'text/css; charset=utf8',
49+
'.svg': 'image/svg+xml',
50+
'.json': 'application/json; charset=utf8',
51+
'.html': 'text/html; charset=utf8'
52+
}
53+
54+
/**
55+
* create a web server that serves an asset if it exists or index.html if not,
56+
* this simulates the behaviour of Cloudflare with `./dist/_redirects`
57+
*/
58+
function createFrontend (): Server {
59+
return createServer((req, res) => {
60+
let file = req.url
61+
62+
if (file == null || file === '/') {
63+
file = 'index.html'
64+
}
65+
66+
let asset = join('./dist', file)
67+
68+
if (!existsSync(asset)) {
69+
// serve index.html instead of 404ing
70+
asset = './dist/index.html'
71+
}
72+
73+
res.statusCode = 200
74+
res.setHeader('content-type', MIME_TYPES[extname(asset)] ?? 'application/octet-stream')
75+
createReadStream(asset).pipe(res)
76+
})
77+
}
78+
4579
export interface ServeOptions {
4680
shouldLoadFixtures?: boolean
4781
shouldStartFrontend?: boolean
@@ -54,37 +88,42 @@ export async function serve ({ shouldLoadFixtures = false, shouldStartFrontend =
5488
controller: KuboNode
5589
}> {
5690
let controller: KuboNode
91+
5792
if (shouldLoadFixtures) {
5893
const fixtures = await loadFixtures()
5994
controller = fixtures.controller
60-
// IPFS_NS_MAP = fixtures.IPFS_NS_MAP
6195
} else {
6296
controller = await createKuboNode()
6397
}
6498

6599
// sets up kubo node and ipfs gateway
66100
const ipfsGateway = await setupIpfsGateway()
67-
101+
/*
68102
// sets up reverse proxy for front-end assets being auto-loaded
69103
const reverseProxy = createReverseProxy({
70104
backendPort: shouldStartFrontend ? 8345 : 3000, // front-end server port. 3000 if playwright is running, 8345 if build.js starts the server
71105
proxyPort: 3333
72106
})
107+
*/
108+
// rebuild the app on changes
109+
const build = shouldStartFrontend ? execa('node', ['build.js', '--watch']) : undefined
110+
build?.stdout?.pipe(process.stdout)
111+
build?.stderr?.pipe(process.stderr)
73112

74-
// call build.js with --serve and --watch flags, piping the output to the console
75-
const frontend = shouldStartFrontend ? execa('node', ['build.js', '--serve', '--watch']) : undefined
76-
77-
frontend?.stdout?.pipe(process.stdout)
78-
frontend?.stderr?.pipe(process.stderr)
113+
// serve the dist folder similarly to how cloudflare does
114+
const frontend = createFrontend()
115+
frontend.listen(3333)
79116

80117
const cleanup = async (): Promise<void> => {
81-
frontend?.kill()
82-
reverseProxy.close()
118+
build?.kill()
119+
// reverseProxy.close()
83120
await ipfsGateway.stop()
121+
frontend.close()
122+
frontend.closeAllConnections()
84123
}
85124

86125
// when the process exits, stop the reverse proxy
87-
frontend?.on('exit', () => { void cleanup() })
126+
build?.on('exit', () => { void cleanup() })
88127
process.on('SIGINT', () => { void cleanup() })
89128
process.on('SIGTERM', () => { void cleanup() })
90129

@@ -95,5 +134,14 @@ export async function serve ({ shouldLoadFixtures = false, shouldStartFrontend =
95134

96135
// Run main function if this file is being executed directly
97136
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
98-
await serve({ shouldLoadFixtures: args.includes('--load-fixtures'), shouldStartFrontend: true })
137+
const {
138+
controller
139+
} = await serve({ shouldLoadFixtures: args.includes('--load-fixtures'), shouldStartFrontend: true })
140+
141+
const info = await controller.info()
142+
143+
// eslint-disable-next-line no-console
144+
console.info('Kubo gateway:', info.gateway)
145+
// eslint-disable-next-line no-console
146+
console.info('Kubo RPC API:', info.api)
99147
}

src/lib/path-or-subdomain.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,6 @@ export const toSubdomainRequest = (location: URL): URL => {
7777
.split('/')
7878
.filter(segment => segment !== '')
7979

80-
// remove cloudflare redirect
81-
if (segments[0] === 'index.html') {
82-
segments.shift()
83-
}
84-
8580
if (segments.length < 2) {
8681
throw new InvalidParametersError(`Invalid location ${location}`)
8782
}

0 commit comments

Comments
 (0)