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: create @helia/verified-fetch #392

Merged
merged 108 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
2a66379
feat: create @helia/verified-fetch
SgtPooki Jan 17, 2024
ab0f994
fix: dep-check passes with no warnings
SgtPooki Jan 18, 2024
7a5dc75
test: adding some tests
SgtPooki Jan 18, 2024
8c15f05
test: adding gateway test
SgtPooki Jan 18, 2024
94cf631
chore: lint succeeds
SgtPooki Jan 18, 2024
56008e8
chore: fix dep-check
SgtPooki Jan 18, 2024
b8a5f67
docs: update custom helia example
SgtPooki Jan 18, 2024
84adcbb
Update packages/verified-fetch/src/interface.ts
SgtPooki Jan 18, 2024
603fb7f
docs: Update packages/verified-fetch/README.md
SgtPooki Jan 18, 2024
a49d353
docs: remove support for CID string
SgtPooki Jan 18, 2024
2444ca3
chore: change default mime-type
SgtPooki Jan 18, 2024
a92ed83
chore: car & ipns-record return 501 not implemented
SgtPooki Jan 18, 2024
6b42abe
chore: address header comments
SgtPooki Jan 18, 2024
2dd264f
test: add fixture for importing CID content from the network
SgtPooki Jan 18, 2024
516d896
test: add test for multiblock-json unixfs content
SgtPooki Jan 18, 2024
ccb1739
chore: fix types and tests
SgtPooki Jan 18, 2024
44c4c20
fix: unmarshal unixfs data with transform stream
SgtPooki Jan 18, 2024
22cadfe
chore: many updates
SgtPooki Jan 18, 2024
16a2629
fix: url parsing in firefox
SgtPooki Jan 19, 2024
58a2c87
Merge branch 'main' into feat/create-verified-fetch
SgtPooki Jan 19, 2024
ade40b2
test: test than IPNS:// urls are handled properly
SgtPooki Jan 19, 2024
4cc599a
test: peerId urls
SgtPooki Jan 19, 2024
ff25ff1
feat: support custom modules in verifiedFetch constructor
SgtPooki Jan 19, 2024
3f347d8
fix: dep-check
SgtPooki Jan 19, 2024
b11db65
chore: change unixfs stream log from error to trace
SgtPooki Jan 22, 2024
84ef988
Merge branch 'main' into feat/create-verified-fetch
SgtPooki Jan 22, 2024
71c1b74
chore: move verified-fetch interop tests
SgtPooki Jan 22, 2024
0f20f0b
fix: peer-job-queue import in @libp2p/circuit-relay
SgtPooki Jan 22, 2024
20803f9
test: move verified-fetch e2e tests to @helia/interop
SgtPooki Jan 22, 2024
b96fd28
fix: return 501 for directories without root
SgtPooki Jan 22, 2024
fae6ea3
chore: remove signal from .cat options
SgtPooki Jan 22, 2024
fb5e883
test(interop): verified-fetch returns 501 on dir without root file
SgtPooki Jan 22, 2024
27abe76
test(verified-fetch): re-enable heliaP2P instantiation
SgtPooki Jan 22, 2024
3db9838
test: disable delegated routing in browsers
SgtPooki Jan 22, 2024
250ad55
chore: minor version and test fixes
SgtPooki Jan 22, 2024
254b94e
fix: parse-url-string supports queryStrings
SgtPooki Jan 22, 2024
129b560
test: add tests for unimplemented formats
SgtPooki Jan 22, 2024
b76e16c
test: move parse-resource out of verifiedFetch class
SgtPooki Jan 23, 2024
a76b836
chore: remove file-type mentions and unixFsTransformStream
SgtPooki Jan 23, 2024
a01398a
test: content-type tests
SgtPooki Jan 23, 2024
6e21e06
test: add url parse failure states
SgtPooki Jan 23, 2024
b32eb7e
chore: some more moving around
SgtPooki Jan 23, 2024
e4f4a94
test(verified-fetch): root lookup for vnd.ipld.raw
SgtPooki Jan 23, 2024
a1e6bf8
test(verified-fetch): 501 on failure to find root file
SgtPooki Jan 23, 2024
1692c61
test(verified-fetch): get-stream-and-content-type
SgtPooki Jan 23, 2024
0290d5e
test(verified-fetch): capture last iter value when done
SgtPooki Jan 23, 2024
dee5095
fix: some dag-json CID support
SgtPooki Jan 23, 2024
539fe9a
chore: remove noisy onProgress trace log
SgtPooki Jan 23, 2024
a25d5b0
test(interop): verified-fetch for blog.libp2p.io
SgtPooki Jan 23, 2024
a40369d
feat: json CID support
SgtPooki Jan 24, 2024
7802acb
chore: remove duplicate return of default mime type
SgtPooki Jan 24, 2024
aad723a
test(verified-fetch): parse-resource failure case
SgtPooki Jan 24, 2024
44d6c82
test(verified-fetch): stop and start coverage
SgtPooki Jan 24, 2024
96adb51
test(verified-fetch): parse-url-string coverage
SgtPooki Jan 24, 2024
48d960b
chore: remove dns.quad9 from resolver due to CORS
SgtPooki Jan 24, 2024
5f75863
Merge branch 'main' into feat/create-verified-fetch
SgtPooki Jan 25, 2024
cb3e95e
chore: use latest deployed versions of packages
SgtPooki Jan 25, 2024
0e3a767
chore: remove unused fixture fn
SgtPooki Jan 25, 2024
6a25298
chore: add @helia/verified-fetch after main merge
SgtPooki Jan 25, 2024
28a2dc4
chore: add onProgress event types
SgtPooki Jan 25, 2024
9476118
feat: add some onProgress events
SgtPooki Jan 25, 2024
09d8349
feat: pipe through onProgress events
SgtPooki Jan 25, 2024
0538e24
test: add hamt-sharded-directory test
SgtPooki Jan 25, 2024
ce51c89
chore: revert handleIPLDRaw changes in last commit
SgtPooki Jan 25, 2024
1747cc2
test: skip HAMT test until we get a smaller fixture
SgtPooki Jan 26, 2024
a55b172
chore: Apply suggestions from code review
SgtPooki Jan 26, 2024
9293622
chore: add init obj typeguard for createVerifiedFetch
SgtPooki Jan 26, 2024
9b2fa77
fix: replace magic code numbers with imports of actual codes
SgtPooki Jan 26, 2024
8dcb35a
chore: cache-control on
SgtPooki Jan 26, 2024
c8f3cff
chore: type fixes
SgtPooki Jan 26, 2024
d0d7fba
feat: optimizations to reduce if branching
SgtPooki Jan 26, 2024
fdd8980
docs: npm description -> trustless+verified
SgtPooki Jan 26, 2024
f864f44
chore: replace fixture server with aegir/fixtures
SgtPooki Jan 26, 2024
b177f3e
chore: remove empty .aegir.js config file
SgtPooki Jan 26, 2024
ec664a8
chore: remove typeVersions from package.json
SgtPooki Jan 26, 2024
db3dd3a
chore: remove unused browser property in package.json
SgtPooki Jan 26, 2024
deb9c1f
chore: move ParsedUrlStringResults
SgtPooki Jan 26, 2024
e88b62b
chore: move CreateVerifiedFetchWithOptions
SgtPooki Jan 26, 2024
9a0c13c
chore: moved types
SgtPooki Jan 26, 2024
cb09852
fix: onProgress detail should be object, not detail.detail
SgtPooki Jan 26, 2024
2845b0e
docs: move large chunk of README to @packageDocumentation
SgtPooki Jan 26, 2024
a34119b
chore: parse-url-string parsing order
SgtPooki Jan 26, 2024
c42b99b
feat: support @helia/ipns onProgress
SgtPooki Jan 29, 2024
8bc259c
feat: cache ipns lookups
SgtPooki Jan 30, 2024
b520235
chore: split constructor args
SgtPooki Jan 30, 2024
25444d7
chore: add tlru cache copy from what is used by @helia/ipns
SgtPooki Jan 30, 2024
99b7066
fix: verifiedFetch accepts fetch like signal
SgtPooki Jan 30, 2024
0e0c287
feat: add dag-cbor direct support
SgtPooki Jan 30, 2024
2d90412
test: unixfs-chunked json test name
SgtPooki Jan 30, 2024
4890b6b
fix: @helia/ipns doesn't enforce no-path
SgtPooki Jan 30, 2024
a669b28
Merge branch 'main' into feat/create-verified-fetch
SgtPooki Jan 31, 2024
97f6cf3
chore: verified-fetch uses latest @helia/ipns
SgtPooki Jan 31, 2024
6d05614
fix(verified-fetch): only check for index.html in dirs
SgtPooki Feb 1, 2024
08580bf
docs: close block & better videoStream var name
SgtPooki Feb 1, 2024
793ecb4
docs: example gateway urls
SgtPooki Feb 1, 2024
b488bc9
docs: addressing more comments
SgtPooki Feb 1, 2024
f1098cf
chore: 501 for explicit vnd.ipld.raw requests
SgtPooki Feb 1, 2024
e073d1f
feat: use ipfs-unixfs-exporter for walking paths
SgtPooki Feb 1, 2024
feac1a0
feat: support raw codec
SgtPooki Feb 1, 2024
2491c19
chore: edits for consistency, update project config
achingbrain Feb 2, 2024
d496d98
chore: simplify factory
achingbrain Feb 2, 2024
53699d0
chore: update readme and fix linting
achingbrain Feb 2, 2024
3da55b9
fix: use helia logger
achingbrain Feb 2, 2024
e21ca11
chore: fix types and tests
achingbrain Feb 2, 2024
5d10747
chore: cids as objects until stringinfication is necessary
achingbrain Feb 2, 2024
4a514bd
fix: remove unused var and make process events consistent
achingbrain Feb 2, 2024
a855339
chore: simplify factory again
achingbrain Feb 2, 2024
c590a47
fix: allow tree shaking
achingbrain Feb 2, 2024
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
45 changes: 45 additions & 0 deletions packages/verified-fetch/.aegir.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import getPort from 'aegir/get-port'
import { createServer } from 'ipfsd-ctl'
import * as kuboRpcClient from 'kubo-rpc-client'

/** @type {import('aegir').PartialOptions} */
export default {
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved
build: {
bundlesizeMax: '10kB',
},
test: {
files: './dist/test/*.spec.js',
before: async (options) => {
const ipfsdPort = await getPort()
const ipfsdServer = await createServer({
host: '127.0.0.1',
port: ipfsdPort
}, {
ipfsBin: (await import('kubo')).default.path(),
kuboRpcModule: kuboRpcClient,
ipfsOptions: {
// TODO: enable delegated routing
// TODO: enable trustless-gateway
config: {
Addresses: {
Swarm: [
"/ip4/0.0.0.0/tcp/0",
"/ip4/0.0.0.0/tcp/0/ws"
]
}
}
}
}).start()

return {
env: {
IPFSD_SERVER: `http://127.0.0.1:${ipfsdPort}`,
},
ipfsdServer
}
},
after: async (options, beforeResult) => {
await beforeResult.ipfsdServer.stop()
}
}
}
4 changes: 4 additions & 0 deletions packages/verified-fetch/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This project is dual licensed under MIT and Apache-2.0.

MIT: https://www.opensource.org/licenses/mit
Apache-2.0: https://www.apache.org/licenses/license-2.0
5 changes: 5 additions & 0 deletions packages/verified-fetch/LICENSE-APACHE
Original file line number Diff line number Diff line change
@@ -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.
19 changes: 19 additions & 0 deletions packages/verified-fetch/LICENSE-MIT
Original file line number Diff line number Diff line change
@@ -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.
204 changes: 204 additions & 0 deletions packages/verified-fetch/README.md
Copy link
Member

Choose a reason for hiding this comment

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

For the initial release, it would be useful to demonstrate value added by the library by having examples similar to https://github.com/ipfs/helia/tree/main/packages/ipns#example---getting-started right in the README.

We already have tests for these, just need to add HTML+JS snippets to README:

  • dag-cbor read via .json()
  • UnixFS JSON read via .json()
  • plain text file in UnixFS HAMT read via .text()
  • <img> having src set to data:image/jpg;base64,[...] with payload read via .arrayBuffer()

Copy link
Member Author

Choose a reason for hiding this comment

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

the examples are in @packageDocumentation of src/index.ts now and will be copied over to README when merged

Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<p align="center">
<a href="https://github.com/ipfs/helia" title="Helia">
<img src="https://raw.githubusercontent.com/ipfs/helia/main/assets/helia.png" alt="Helia logo" width="300" />
</a>
</p>

[![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.svg?style=flat-square)](https://codecov.io/gh/ipfs/helia)
[![CI](https://img.shields.io/github/actions/workflow/status/ipfs/helia/main.yml?branch=main\&style=flat-square)](https://github.com/ipfs/helia/actions/workflows/main.yml?query=branch%3Amain)

> A fetch-like API for IPFS content on the web.

# About

`@helia/verified-fetch`` is a library that provides a fetch-like API for fetching content from IPFS. This library should act as a replacement for the `fetch()` API for fetching content from IPFS, and will return a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object that can be used in a similar manner to the `fetch()` API. This means browser and HTTP caching inside browser main threads, web-workers, and service workers, as well as other features of the `fetch()` API should work in a way familiar to developers.
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved

## Example

```ts
import { createVerifiedFetch } from '@helia/verified-fetch'

const verifiedFetch = await createVerifiedFetch({
gateways: ['mygateway.info', 'trustless-gateway.link']
})

const resp = await verifiedFetch('ipfs://bafy...')

const json = await resp.json()
```

# Install

```console
$ npm i @helia/verified-fetch
```

## Browser `<script>` tag

Loading this module through a script tag will make it's exports available as `HeliaVerifiedFetch` in the global namespace.

```html
<script src="https://unpkg.com/@helia/verified-fetch/dist/index.min.js"></script>
```

### Configuration
Copy link
Member

Choose a reason for hiding this comment

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

All of this exposition needs to move into the @packageDocumentation block of /src/index.ts


#### Usage with customized Helia

You can see variations of Helia and js-libp2p configuration options at https://helia.io/interfaces/helia.index.HeliaInit.html.

The `@helia/http` module is currently in-progress, but the init options should be a subset of the `helia` module's init options. See https://github.com/ipfs/helia/issues/289 for more information.

```ts
import { createVerifiedFetch } from '@helia/verified-fetch'
import { CreateHelia as CreateHeliaHttpOnly } from '@helia/http'

const verifiedFetch = await createVerifiedFetch(
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved
CreateHeliaHttpOnly({
gateways: ['mygateway.info', 'trustless-gateway.link'],
routers: ['delegated-ipfs.dev'],
})
)

const resp = await verifiedFetch('ipfs://bafy...')

const json = await resp.json()
```

### Comparison to fetch

First, this library will require instantiation in order to configure the gateways and delegated routers, or potentially a custom Helia instance. Secondly, once your verified-fetch method is created, it will act as similar to the `fetch()` API as possible.

[The `fetch()` API](https://developer.mozilla.org/en-US/docs/Web/API/fetch) takes two parameters:

1. A [resource](https://developer.mozilla.org/en-US/docs/Web/API/fetch#resource)
2. An [options object](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options)

#### Resource argument

This library intends to support the following methods of fetching web3 content from IPFS:

1. IPFS protocol: `ipfs://<cidv0>` & `ipfs://<cidv0>`
2. IPNS protocol: `ipns://<peerId>` & `ipns://<publicKey>` & `ipns://<hostUri_Supporting_DnsLink_TxtRecords>`
3. CID instances: An actual CID instance `CID.parse('bafy...')`
4. CID strings: A CID string `bafy...`

As well as support for pathing & params for all of the above according to [IPFS - Path Gateway Specification](https://specs.ipfs.tech/http-gateways/path-gateway) & [IPFS - Trustless Gateway Specification](https://specs.ipfs.tech/http-gateways/trustless-gateway/). Further refinement of those specifications specifically for web-based scenarios can be found in the [Web Pathing Specification IPIP](https://github.com/ipfs/specs/pull/453).

#### Options argument

This library will not plan to support the exact Fetch API options object, as some of the arguments don't make sense. Instead, it will only support options necessary to meet [IPFS specs](https://specs.ipfs.tech/) related to specifying the resultant shape of desired content.

Some of those header specifications are:

1. https://specs.ipfs.tech/http-gateways/path-gateway/#request-headers
2. https://specs.ipfs.tech/http-gateways/trustless-gateway/#request-headers
3. https://specs.ipfs.tech/http-gateways/subdomain-gateway/#request-headers

Where possible, options and Helia internals will be automatically configured to the appropriate codec & content type based on the `verified-fetch` configuration and `options` argument passed.

Known Fetch API options that will be supported:

1. `signal` - An AbortSignal that a user can use to abort the request.
2. `redirect` - A string that specifies the redirect type. One of `follow`, `error`, or `manual`. Defaults to `follow`. Best effort to adhere to the [Fetch API redirect](https://developer.mozilla.org/en-US/docs/Web/API/fetch#redirect) parameter.
3. `headers` - An object of headers to be sent with the request. Best effort to adhere to the [Fetch API headers](https://developer.mozilla.org/en-US/docs/Web/API/fetch#headers) parameter.
- `accept` - A string that specifies the accept header. Relevant values:
- [`vnd.ipld.raw`](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw). (default)
- [`vnd.ipld.car`](https://www.iana.org/assignments/media-types/application/vnd.ipld.car)
- [`vnd.ipfs.ipns-record`](https://www.iana.org/assignments/media-types/application/vnd.ipfs.ipns-record)
4. `method` - A string that specifies the HTTP method to use for the request. Defaults to `GET`. Best effort to adhere to the [Fetch API method](https://developer.mozilla.org/en-US/docs/Web/API/fetch#method) parameter.
5. `body` - An object that specifies the body of the request. Best effort to adhere to the [Fetch API body](https://developer.mozilla.org/en-US/docs/Web/API/fetch#body) parameter.
6. `cache` - Will basically act as `force-cache` for the request. Best effort to adhere to the [Fetch API cache](https://developer.mozilla.org/en-US/docs/Web/API/fetch#cache) parameter.


Non-Fetch API options that will be supported:

1. `onProgress` - Similar to Helia `onProgress` options, this will be a function that will be called with a progress event. Supported progress events are:
- `helia:verified-fetch:error` - An error occurred during the request.
- `helia:verified-fetch:request:start` - The request has been sent
- `helia:verified-fetch:request:complete` - The request has been sent
- `helia:verified-fetch:request:error` - An error occurred during the request.
- `helia:verified-fetch:request:abort` - The request was aborted prior to completion.
- `helia:verified-fetch:response:start` - The initial HTTP Response headers have been set, and response stream is started.
- `helia:verified-fetch:response:complete` - The response stream has completed.
- `helia:verified-fetch:response:error` - An error occurred while building the response.
Copy link
Member Author

Choose a reason for hiding this comment

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

We should have a discussion about what progress events we actually want

Copy link
Member Author

Choose a reason for hiding this comment

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

onProgress events should help answer the following questions:

  • did I finish resolving IPNS name / peerId
  • was I able to find the terminal element, if not, why not.
  • were there any redirects?
  • download progress for terminal elements (chunk counter?)
  • did we find who has the data (providers)?

Copy link
Member Author

Choose a reason for hiding this comment

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

'if async custom work, should probably have async event':
custom onprogress:

  • redirects?
  • progress?

the rest should be piped up from other helia Modules used.


Some in-flight specs (IPIPs) that will affect the options object this library supports in the future can be seen at https://specs.ipfs.tech/ipips, but a few that I'm aware of are:

1. [IPIP-0412: Signaling Block Order in CARs on HTTP Gateways](https://specs.ipfs.tech/ipips/ipip-0412/)
2. [IPIP-0402: Partial CAR Support on Trustless Gateways](https://specs.ipfs.tech/ipips/ipip-0402/)
3. [IPIP-0386: Subdomain Gateway Interop with _redirects](https://specs.ipfs.tech/ipips/ipip-0386/)
4. [IPIP-0328: JSON and CBOR Response Formats on HTTP Gateways](https://specs.ipfs.tech/ipips/ipip-0328/)
5. [IPIP-0288: TAR Response Format on HTTP Gateways](https://specs.ipfs.tech/ipips/ipip-0288/)

#### Response types

This library's purpose is to return reasonably representable content from IPFS. In other words, fetching content is intended for leaf-node content -- such as images/videos/audio & other assets, or other IPLD content (with link) -- that can be represented by https://developer.mozilla.org/en-US/docs/Web/API/Response#instance_methods. The content type you receive back will depend upon the CID you request as well as the `Accept` header value you provide.

All content we retrieve from the IPFS network is obtained via an AsyncIterable, and will be set as the [body of the HTTP Response](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#body) via a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#consuming_a_fetch_as_a_stream) or other efficient method that avoids loading the entire response into memory or getting the entire response from the network before returning a response to the user.

If your content doesn't have a mime-type or an [IPFS spec](https://specs.ipfs.tech), this library will not support it, but you can use the [`helia`](https://github.com/ipfs/helia) library directly for those use cases. See [Unsupported response types](#unsupported-response-types) for more information.
Copy link
Member Author

Choose a reason for hiding this comment

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

We should rephrase this to reflect our last Helia WG meeting decision to have this library

return the same response as what a user gets when doing curl https://ipfs.io/ip[fn]s/blah

We should also note that since this library is not "a gateway" that mimicking every response type will not be possible and that a wrapper library/server would be needed for those cases.


##### Handling response types

For handling responses we want to follow conventions/abstractions from Fetch API where possible:

- For JSON, assuming you abstract any differences between dag-json/dag-cbor/json/and json-file-on-unixfs, you would call `.json()` to get a JSON object.
- For images (or other web-relevant asset) you want to add to the DOM, use `.blob()` or `.arrayBuffer()` to get the raw bytes.
- For plain text in utf-8, you would call `.text()`
- For streaming response data, use something like `response.body.getReader()` to get a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#consuming_a_fetch_as_a_stream).

##### Unsupported response types

* Returning IPLD nodes or DAGs as JS objects is not supported, as there is no currently well-defined structure for representing this data in an [HTTP Response](https://developer.mozilla.org/en-US/docs/Web/API/Response). Instead, users should request `aplication/vnd.ipld.car` or use the [`helia`](https://github.com/ipfs/helia) library directly for this use case.
* Others? Open an issue or PR!

#### Response headers

This library will set the [HTTP Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) headers to the appropriate values for the content type according to the appropriate [IPFS Specifications](https://specs.ipfs.tech/).

Some known header specifications:

* https://specs.ipfs.tech/http-gateways/path-gateway/#response-headers
* https://specs.ipfs.tech/http-gateways/trustless-gateway/#response-headers
* https://specs.ipfs.tech/http-gateways/subdomain-gateway/#response-headers

#### Possible Scenarios that could cause confusion

##### Attempting to fetch the CID for content that does not make sense

If you request `bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze`, which points to the root of the en.wikipedia.org mirror, a response object does not make sense.

#### Errors

Known Errors that can be thrown:

1. `TypeError` - If the resource argument is not a string, CID, or CID string.
2. `TypeError` - If the options argument is passed and not an object.
3. `TypeError` - If the options argument is passed and is malformed.
4. `AbortError` - If the content request is aborted due to user aborting provided AbortSignal.

# API Docs

- <https://ipfs.github.io/helia/modules/_helia_verified_fetch.html>

# License

Licensed under either of

- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT ([LICENSE-MIT](LICENSE-MIT) / <http://opensource.org/licenses/MIT>)

# Contribute

Contributions welcome! Please check out [the issues](https://github.com/ipfs/helia/issues).

Also see our [contributing document](https://github.com/ipfs/community/blob/master/CONTRIBUTING_JS.md) for more information on how we work, and about contributing in general.

Please be aware that all interactions related to this repo are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)
82 changes: 82 additions & 0 deletions packages/verified-fetch/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"name": "@helia/verified-fetch",
"version": "0.0.0",
"description": "A fetch-like API for IPFS content on the web.",
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved
"license": "Apache-2.0 OR MIT",
"homepage": "https://github.com/ipfs/helia/tree/main/packages/verified-fetch#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/ipfs/helia.git"
},
"bugs": {
"url": "https://github.com/ipfs/helia/issues"
},
"publishConfig": {
"access": "public",
"provenance": true
},
"keywords": [
"IPFS",
"fetch",
"helia"
],
"type": "module",
"types": "./dist/src/index.d.ts",
"files": [
"src",
"dist",
"!dist/test",
"!**/*.tsbuildinfo"
],
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/src/index.js"
}
},
"eslintConfig": {
"extends": "ipfs",
"parserOptions": {
"project": true,
"sourceType": "module"
}
},
"scripts": {
"clean": "aegir clean",
"lint": "aegir lint",
"dep-check": "aegir dep-check",
"build": "aegir build",
"test": "aegir test",
"test:chrome": "aegir test -t browser --cov",
"test:chrome-webworker": "aegir test -t webworker",
"test:firefox": "aegir test -t browser -- --browser firefox",
"test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
"test:node": "aegir test -t node --cov",
"test:electron-main": "aegir test -t electron-main"
},
"dependencies": {
"@helia/block-brokers": "next",
"@helia/http": "next",
"@helia/interface": "next",
"@helia/ipns": "next",
"@helia/routers": "next",
"@helia/unixfs": "next",
"@libp2p/peer-id": "^4.0.5",
"mime-types": "^2.1.35",
"multiformats": "^13.0.0"
},
"devDependencies": {
"@types/mime-types": "^2.1.4",
"@types/sinon": "^17.0.2",
"aegir": "^42.1.0",
"helia": "next",
"ipfs-unixfs": "^11.1.2",
"ipfsd-ctl": "^13.0.0",
"kubo": "^0.25.0",
"kubo-rpc-client": "^3.0.2"
},
"browser": {
"node:buffer": false,
"node:stream": false
}
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading