diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d401a77 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: +- package-ecosystem: npm + directory: "/" + schedule: + interval: daily + time: "10:00" + open-pull-requests-limit: 20 + commit-message: + prefix: "deps" + prefix-development: "deps(dev)" diff --git a/.github/workflows/semantic-pull-request.yml b/.github/workflows/semantic-pull-request.yml new file mode 100644 index 0000000..bd00f09 --- /dev/null +++ b/.github/workflows/semantic-pull-request.yml @@ -0,0 +1,12 @@ +name: Semantic PR + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + uses: pl-strflt/.github/.github/workflows/reusable-semantic-pull-request.yml@v0.3 diff --git a/.gitignore b/.gitignore index a4979be..7ecacf3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,139 +1,11 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist +node_modules build - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* -/test-results/ -/playwright-report/ -/playwright/.cache/ -screenshots -.envrc -scripts/tmp/fixtures -scripts/tmp/kubo-path.txt -test/fixtures/e2e +dist +.docs +.coverage +node_modules +package-lock.json +yarn.lock +.vscode +playwright-report +test diff --git a/LICENSE b/LICENSE index 4a3e1c6..20ce483 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,4 @@ -MIT License +This project is dual licensed under MIT and Apache-2.0. -Copyright (c) 2023 Nishant Arora - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..14478a3 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..72dc60d --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 7048339..08b4035 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,30 @@ # helia-http-gateway -Docker images for Helia. +[![ipfs.tech](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](https://ipfs.tech) +[![Discuss](https://img.shields.io/discourse/https/discuss.ipfs.tech/posts.svg?style=flat-square)](https://discuss.ipfs.tech) +[![codecov](https://img.shields.io/codecov/c/github/ipfs/helia-http-gateway.svg?style=flat-square)](https://codecov.io/gh/ipfs/helia-http-gateway) +[![CI](https://img.shields.io/github/actions/workflow/status/ipfs/helia-http-gateway/gateway-conformance.yml?branch=main\&style=flat-square)](https://github.com/ipfs/helia-http-gateway/actions/workflows/gateway-conformance.yml?query=branch%3Amain) -## Purpose +> HTTP IPFS Gateway implemented using Helia -This container image hosts helia in a node container. It implements [HTTP IPFS-gateway API](https://docs.ipfs.tech/concepts/ipfs-gateway/#gateway-types) and responds to the incoming requests using helia to fetch the content from IPFS. +# About + + + +A Dockerized application that implements the [HTTP IPFS-gateway API](https://docs.ipfs.tech/concepts/ipfs-gateway/#gateway-types) spec and responds to the incoming requests using [Helia](https://github.com/ipfs/helia) to fetch the content from IPFS. ## Run from the github container registry @@ -12,7 +32,7 @@ This container image hosts helia in a node container. It implements [HTTP IPFS-g $ docker run -it -p 8080:8080 ghcr.io/ipfs/helia-http-gateway:latest ``` -See https://github.com/ipfs/helia-http-gateway/pkgs/container/helia-http-gateway for more information. +See for more information. ## Run Using Docker Compose @@ -23,6 +43,7 @@ $ docker-compose up ## Run Using Docker ### Build + ```sh $ docker build . --tag helia-http-gateway:local ``` @@ -39,23 +60,37 @@ $ docker build . --platform linux/arm64 --tag helia-http-gateway:local-arm64 $ docker run -it -p 8080:8080 -e DEBUG="helia-http-gateway*" helia-http-gateway:local # or helia-http-gateway:local-arm64 ``` +## Run without Docker + +\### Build + +```sh +$ npm run build +``` + +### Running + +```sh +$ npm start +``` + ## Supported Environment Variables -| Variable | Description | Default | -| --- | --- | --- | -| `DEBUG` | Debug level | `''`| -| `FASTIFY_DEBUG` | Debug level for fastify's logger | `''`| -| `PORT` | Port to listen on | `8080` | -| `HOST` | Host to listen on | `0.0.0.0` | -| `USE_SUBDOMAINS` | Whether to use [origin isolation](https://docs.ipfs.tech/how-to/gateway-best-practices/#use-subdomain-gateway-resolution-for-origin-isolation) | `true` | -| `METRICS` | Whether to enable prometheus metrics. Any value other than 'true' will disable metrics. | `true` | -| `USE_BITSWAP` | Use bitswap to fetch content from IPFS | `true` | -| `USE_TRUSTLESS_GATEWAYS` | Whether to fetch content from trustless-gateways or not | `true` | -| `TRUSTLESS_GATEWAYS` | Comma separated list of trusted gateways to fetch content from | [Defined in Helia](https://github.com/ipfs/helia/blob/main/packages/helia/src/block-brokers/trustless-gateway/index.ts) | -| `USE_LIBP2P` | Whether to use libp2p networking | `true` | -| `ECHO_HEADERS` | A debug flag to indicate whether you want to output request and response headers | `false` | -| `USE_DELEGATED_ROUTING` | Whether to use the delegated routing v1 API | `true` | -| `DELEGATED_ROUTING_V1_HOST` | Hostname to use for delegated routing v1 | `https://delegated-ipfs.dev` | +| Variable | Description | Default | +| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `DEBUG` | Debug level | `''` | +| `FASTIFY_DEBUG` | Debug level for fastify's logger | `''` | +| `PORT` | Port to listen on | `8080` | +| `HOST` | Host to listen on | `0.0.0.0` | +| `USE_SUBDOMAINS` | Whether to use [origin isolation](https://docs.ipfs.tech/how-to/gateway-best-practices/#use-subdomain-gateway-resolution-for-origin-isolation) | `true` | +| `METRICS` | Whether to enable prometheus metrics. Any value other than 'true' will disable metrics. | `true` | +| `USE_BITSWAP` | Use bitswap to fetch content from IPFS | `true` | +| `USE_TRUSTLESS_GATEWAYS` | Whether to fetch content from trustless-gateways or not | `true` | +| `TRUSTLESS_GATEWAYS` | Comma separated list of trusted gateways to fetch content from | [Defined in Helia](https://github.com/ipfs/helia/blob/main/packages/helia/src/block-brokers/trustless-gateway/index.ts) | +| `USE_LIBP2P` | Whether to use libp2p networking | `true` | +| `ECHO_HEADERS` | A debug flag to indicate whether you want to output request and response headers | `false` | +| `USE_DELEGATED_ROUTING` | Whether to use the delegated routing v1 API | `true` | +| `DELEGATED_ROUTING_V1_HOST` | Hostname to use for delegated routing v1 | `https://delegated-ipfs.dev` | + * + * See the source of truth for all `process.env.` environment variables at [src/constants.ts](src/constants.ts). + * + * You can also see some recommended environment variable configurations at: + * + * - [./.env-all](./.env-all) + * - [./.env-delegated-routing](./.env-delegated-routing) + * - [./.env-gwc](./.env-gwc) + * - [./.env-trustless-only](./.env-trustless-only) + * + * ### Running with custom configurations + * + * Note that any of the following calls to docker can be replaced with something like `MY_ENV_VAR="MY_VALUE" npm run start` + * + * #### Disable libp2p + * + * ```sh + * $ docker run -it -p $PORT:8080 -e DEBUG="helia-http-gateway*" -e USE_LIBP2P="false" helia + * ``` + * + * #### Disable bitswap + * + * ```sh + * $ docker run -it -p $PORT:8080 -e DEBUG="helia-http-gateway*" -e USE_BITSWAP="false" helia + * ``` + * + * #### Disable trustless gateways + * + * ```sh + * $ docker run -it -p $PORT:8080 -e DEBUG="helia-http-gateway*" -e USE_TRUSTLESS_GATEWAYS="false" helia + * ``` + * + * #### Customize trustless gateways + * + * ```sh + * $ docker run -it -p $PORT:8080 -e DEBUG="helia-http-gateway*" -e TRUSTLESS_GATEWAYS="https://ipfs.io,https://dweb.link" helia + * ``` + * + * + * + * ## E2E Testing + * + * We have some tests enabled that simulate running inside of [ProbeLab's Tiros](https://github.com/plprobelab/tiros), via playwright. These tests request the same paths from ipfs.io and ensure that the resulting text matches. This is not a direct replacement for [gateway conformance testing](https://github.com/ipfs/gateway-conformance), but helps us ensure the helia-http-gateway is working as expected. + * + * By default, these tests: + * + * 1. Run in serial + * 2. Allow for up to 5 failures before failing the whole suite run. + * 3. Have an individual test timeout of two minutes. + * + * ### Run e2e tests locally + * + * ```sh + * $ npm run test:e2e # run all tests + * $ npm run test:e2e -- ${PLAYWRIGHT_OPTIONS} # run tests with custom playwright options. + * + * ``` + * + * ### Get clinicjs flamecharts and doctor reports from e2e tests + * + * ```sh + * $ npm run test:e2e-doctor # Run the dev server with clinicjs doctor, execute e2e tests, and generate a report. + * $ npm run test:e2e-flame # Run the dev server with clinicjs flame, execute e2e tests, and generate a report. + * ``` + * + * ## Metrics + * + * Running with `METRICS=true` will enable collecting Fastify/libp2p metrics and + * will expose a prometheus collection endpoint at + */ + import compress from '@fastify/compress' import cors from '@fastify/cors' import Fastify from 'fastify' import metricsPlugin from 'fastify-metrics' import { HOST, PORT, METRICS, ECHO_HEADERS, FASTIFY_DEBUG } from './constants.js' -import { HeliaServer, type RouteEntry } from './heliaServer.js' +import { HeliaServer, type RouteEntry } from './helia-server.js' import { logger } from './logger.js' const log = logger.forComponent('index')