@helia/verified-fetch 8.0.4 → 8.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/index.min.js +61 -61
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/index.d.ts +3 -3
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +1 -1
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/utils/canonical-uri.d.ts +9 -0
  8. package/dist/src/utils/canonical-uri.d.ts.map +1 -0
  9. package/dist/src/utils/canonical-uri.js +157 -0
  10. package/dist/src/utils/canonical-uri.js.map +1 -0
  11. package/dist/src/utils/content-type-parser.d.ts.map +1 -1
  12. package/dist/src/utils/content-type-parser.js +54 -4
  13. package/dist/src/utils/content-type-parser.js.map +1 -1
  14. package/dist/src/utils/ipfs-uri.d.ts +8 -0
  15. package/dist/src/utils/ipfs-uri.d.ts.map +1 -0
  16. package/dist/src/utils/ipfs-uri.js +10 -0
  17. package/dist/src/utils/ipfs-uri.js.map +1 -0
  18. package/dist/src/utils/libp2p-defaults.browser.d.ts +2 -1
  19. package/dist/src/utils/libp2p-defaults.browser.d.ts.map +1 -1
  20. package/dist/src/utils/libp2p-defaults.browser.js +13 -8
  21. package/dist/src/utils/libp2p-defaults.browser.js.map +1 -1
  22. package/dist/src/utils/libp2p-defaults.d.ts +2 -1
  23. package/dist/src/utils/libp2p-defaults.d.ts.map +1 -1
  24. package/dist/src/utils/libp2p-defaults.js +3 -7
  25. package/dist/src/utils/libp2p-defaults.js.map +1 -1
  26. package/dist/src/utils/parse-resource.d.ts.map +1 -1
  27. package/dist/src/utils/parse-resource.js +2 -1
  28. package/dist/src/utils/parse-resource.js.map +1 -1
  29. package/dist/src/utils/x-ipfs-path.d.ts +11 -0
  30. package/dist/src/utils/x-ipfs-path.d.ts.map +1 -0
  31. package/dist/src/utils/x-ipfs-path.js +30 -0
  32. package/dist/src/utils/x-ipfs-path.js.map +1 -0
  33. package/dist/src/verified-fetch.d.ts.map +1 -1
  34. package/dist/src/verified-fetch.js +22 -12
  35. package/dist/src/verified-fetch.js.map +1 -1
  36. package/package.json +1 -2
  37. package/src/index.ts +4 -4
  38. package/src/utils/canonical-uri.ts +184 -0
  39. package/src/utils/content-type-parser.ts +54 -4
  40. package/src/utils/ipfs-uri.ts +9 -0
  41. package/src/utils/libp2p-defaults.browser.ts +14 -10
  42. package/src/utils/libp2p-defaults.ts +5 -9
  43. package/src/utils/parse-resource.ts +2 -1
  44. package/src/utils/x-ipfs-path.ts +34 -0
  45. package/src/verified-fetch.ts +22 -12
@@ -3,8 +3,6 @@ import { ipnsResolver } from '@helia/ipns'
3
3
  import { isPeerId, isPublicKey } from '@libp2p/interface'
4
4
  import { CID } from 'multiformats/cid'
5
5
  import { CustomProgressEvent } from 'progress-events'
6
- import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
7
- import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
8
6
  import { MAX_HEADER_VALUE_LENGTH } from './constants.ts'
9
7
  import { CarPlugin } from './plugins/plugin-handle-car.ts'
10
8
  import { IpldPlugin } from './plugins/plugin-handle-ipld.ts'
@@ -20,11 +18,12 @@ import { errorToObject } from './utils/error-to-object.ts'
20
18
  import { errorToResponse } from './utils/error-to-response.ts'
21
19
  import { getETag, ifNoneMatches } from './utils/get-e-tag.ts'
22
20
  import { getRangeHeader } from './utils/get-range-header.ts'
23
- import { toIPFSPath } from './utils/ipfs-url-to-ipfs-path.ts'
21
+ import { toIpfsUri } from './utils/ipfs-uri.ts'
24
22
  import { stringToIpfsUrl } from './utils/parse-resource.ts'
25
23
  import { setCacheControlHeader } from './utils/response-headers.ts'
26
24
  import { notAcceptableResponse, notImplementedResponse, notModifiedResponse } from './utils/responses.ts'
27
25
  import { ServerTiming } from './utils/server-timing.ts'
26
+ import { toXIpfsPath } from './utils/x-ipfs-path.ts'
28
27
  import type { AcceptHeader, CIDDetail, ContentTypeParser, CreateVerifiedFetchOptions, Resource, ResourceDetail, VerifiedFetchInit as VerifiedFetchOptions, VerifiedFetchPlugin, PluginContext, PluginOptions } from './index.ts'
29
28
  import type { DNSLink } from '@helia/dnslink'
30
29
  import type { Helia } from '@helia/interface'
@@ -165,7 +164,15 @@ export class VerifiedFetch {
165
164
  })
166
165
  }
167
166
 
168
- const url = this.parseResource(resource)
167
+ let url: URL
168
+
169
+ try {
170
+ url = this.parseResource(resource)
171
+ } catch (err: any) {
172
+ return this.handleFinalResponse(errorToResponse(resource, err, opts), withServerTiming, {
173
+ serverTiming
174
+ })
175
+ }
169
176
 
170
177
  if (url.protocol === 'ipfs:' && url.pathname === '') {
171
178
  // if we don't need to resolve an IPNS names or traverse a DAG, we can
@@ -431,11 +438,11 @@ export class VerifiedFetch {
431
438
  }
432
439
 
433
440
  if (context?.terminalElement?.cid != null && context?.url != null) {
434
- const protocol = context.url.protocol === 'dnslink:' ? 'ipns:' : context.url.protocol
435
- const path = context.url.pathname
436
- const ipfsUri = `${protocol}//${context.url.hostname}${path === '/' ? '' : path}`
441
+ const ipfsUri = toIpfsUri(context.url)
437
442
 
438
- if (ipfsUri.length < MAX_HEADER_VALUE_LENGTH) {
443
+ // the value is ASCII-only so string length equals byte length; a value
444
+ // of exactly MAX_HEADER_VALUE_LENGTH bytes is still sent
445
+ if (ipfsUri != null && ipfsUri.length <= MAX_HEADER_VALUE_LENGTH) {
439
446
  try {
440
447
  response.headers.set('ipfs-uri', ipfsUri)
441
448
  } catch (err) {
@@ -443,10 +450,13 @@ export class VerifiedFetch {
443
450
  }
444
451
  }
445
452
 
446
- // TODO: remove this after https://github.com/ipfs/specs/issues/547
447
- const ipfsPath = uint8ArrayToString(uint8ArrayFromString(toIPFSPath(context.url), 'ascii'), 'ascii')
453
+ // x-ipfs-path is deprecated by IPIP-0548 in favour of ipfs-uri, and is
454
+ // kept for clients that still read it. It is omitted for content paths
455
+ // that an HTTP field value cannot carry, e.g. a file name with
456
+ // non-ASCII bytes
457
+ const ipfsPath = toXIpfsPath(context.url)
448
458
 
449
- if (ipfsPath.length < MAX_HEADER_VALUE_LENGTH) {
459
+ if (ipfsPath != null && ipfsPath.length <= MAX_HEADER_VALUE_LENGTH) {
450
460
  try {
451
461
  response.headers.set('x-ipfs-path', ipfsPath)
452
462
  } catch (err) {
@@ -464,7 +474,7 @@ export class VerifiedFetch {
464
474
  response.headers.set('access-control-allow-origin', '*')
465
475
  response.headers.set('access-control-allow-methods', 'GET, HEAD, OPTIONS')
466
476
  response.headers.set('access-control-allow-headers', 'Content-Type, Range, User-Agent, X-Requested-With')
467
- response.headers.set('access-control-expose-headers', 'Content-Range, Content-Length, X-Ipfs-Path, X-Ipfs-Roots, X-Chunked-Output, X-Stream-Output')
477
+ response.headers.set('access-control-expose-headers', 'Content-Range, Content-Length, Ipfs-Uri, X-Ipfs-Path, X-Ipfs-Roots, X-Chunked-Output, X-Stream-Output')
468
478
 
469
479
  if (context?.terminalElement?.cid != null && response.headers.get('etag') == null) {
470
480
  const etag = getETag({