Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(server): ⚡️ Subdomain Gateway Using Fastify #31

Merged
merged 10 commits into from
Oct 25, 2023

Conversation

whizzzkid
Copy link
Collaborator

@whizzzkid whizzzkid commented Oct 25, 2023

Closes: #16

In this PR:

  • express -> fastify
  • implemented route redirection host:port/ns/address/path -> address.ns.host:port/path (subdomain)
  • implemented subdomain handling and content fetching.
  • fastify-metrics provides insights into node resources.
  • anecdotal better performance.

Demo:

helia-fastify.mov

Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
Copy link
Member

@SgtPooki SgtPooki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blockers:

  • e2e tests not running locally or in CI: Error: Timed out waiting 60000ms from config.webServer.
  • Logging output is not human-readable?

nits:

  • I prefix on types?

Comment on lines +97 to +112
const { address, namespace } = this.parseHostParts(request.hostname)
const { url: relativePath } = request
this.log('Fetching from Helia:', { address, namespace, relativePath })
// raw response is needed to respond with the correct content type.
for await (const chunk of await this.heliaFetch.fetch({ address, namespace, relativePath })) {
if (type === undefined) {
type = await parseContentType({ bytes: chunk, path: relativePath })
// this needs to happen first.
reply.raw.writeHead(200, {
'Content-Type': type ?? DEFAULT_MIME_TYPE,
'Cache-Control': 'public, max-age=31536000, immutable'
})
}
reply.raw.write(Buffer.from(chunk))
}
this.log('Requesting content from helia:', request.path)
await this.fetchFromHeliaAndWriteToResponse({ response, request })
reply.raw.end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is awesome but it would be ideal to put the header writing into heliaFetch no? heliaFetch should ideally return an HttpResponse object?

can be a TODO

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking from the POV of moving HeliaFetch as a standalone item, it does not parseConetent (yet!) hence only returns the buffer as an AsyncIterable, leaving parsing to whoever is fetching content using helia.

src/index.ts Outdated
// Add the routes
app.get('/', (req, res) => {
res.send('Helia Docker, to fetch a page, call `/ipns/<path>` or `/ipfs/<cid>`')
const app = Fastify({ logger })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like logging isn't as human-readable as before? can we clean that up?

here is some output from startup:

╰─ ✘ 1 ❯ PORT=8888 npm run start:dev

> helia-http-gateway@0.0.1 start:dev
> npm run build && node dist/src/index.js


> helia-http-gateway@0.0.1 build
> aegir build --bundle false

[09:49:39] tsc [started]
[09:49:40] tsc [completed]
Helia Started!
{"level":30,"time":1698252581247,"pid":57765,"hostname":"Russells-MacBook-Pro-314.local","msg":"Server listening at http://0.0.0.0:8888"}

@@ -15,6 +15,12 @@ const ROOT_FILE_PATTERNS = [

const DELEGATED_ROUTING_API = 'https://node3.delegate.ipfs.io/api/v0/name/resolve/'

interface IHeliaPathParts {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
interface IHeliaPathParts {
interface UrlPathParts {

@@ -73,7 +79,7 @@ export class HeliaFetch {
/**
* Parse a path into its namespace, address, and relative path
*/
public parsePath (path: string): { namespace: string, address: string, relativePath: string } {
public parsePath (path: string): IHeliaPathParts {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, if we cache the regex in this function as a static (or global), we should see some significant improvements instead of reconstructing this regex on every path

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you feel that'll help? I'll change it.

whizzzkid and others added 7 commits October 25, 2023 11:50
Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
…ain-gateway' into feat/fastify-subdomain-gateway

* refs/remotes/origin/feat/fastify-subdomain-gateway:
  fix: e2e running with fastify (#32)
Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
@SgtPooki SgtPooki self-requested a review October 25, 2023 21:24
@SgtPooki SgtPooki merged commit 26cb74a into main Oct 25, 2023
1 of 2 checks passed
whizzzkid added a commit that referenced this pull request Oct 26, 2023
* main: (27 commits)
  feat(e2e): add /api/v0/repo/gc test
  chore: disable METRICS on CI e2e test runs
  test: add e2e test for /api/v0/version endpoint
  feat(server): ⚡️ Subdomain Gateway Using Fastify (#31)
  feat: use production level docker settings (#26)
  chore: remove unused playwright init code
  fix: use active LTS in package.json engines
  fix: playwright CI node-version=20
  test: get clinic flame & doctor output from e2e tests
  test: e2e updates
  fix: use HOST constant in healthcheck
  fix: use HOST constant
  test: cleanup playwright test code
  test: add playwright tests
  feat: move HOST,PORT to src/constants.ts
  fix: ✏️  Fixing urls. (#23)
  fix: ✏️ helia-docker -> helia-http-gateway (#22)
  build(deps): Bump @babel/traverse and depcheck (#13)
  feat: add health-check (#21)
  fix(server): 🩹 Using sessionID as a fallback to requests where referer is missing. (#20)
  ...

Signed-off-by: Nishant Arora <1895906+whizzzkid@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

subdomain gateways
2 participants