@helia/verified-fetch 4.1.1 → 5.0.0
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.
- package/README.md +6 -40
- package/dist/index.min.js +73 -534
- package/dist/index.min.js.map +4 -4
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +162 -68
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -40
- package/dist/src/index.js.map +1 -1
- package/dist/src/plugins/index.d.ts +0 -5
- package/dist/src/plugins/index.d.ts.map +1 -1
- package/dist/src/plugins/index.js +0 -4
- package/dist/src/plugins/index.js.map +1 -1
- package/dist/src/plugins/plugin-base.d.ts +8 -9
- package/dist/src/plugins/plugin-base.d.ts.map +1 -1
- package/dist/src/plugins/plugin-base.js +5 -6
- package/dist/src/plugins/plugin-base.js.map +1 -1
- package/dist/src/plugins/plugin-handle-car.d.ts +3 -3
- package/dist/src/plugins/plugin-handle-car.d.ts.map +1 -1
- package/dist/src/plugins/plugin-handle-car.js +38 -39
- package/dist/src/plugins/plugin-handle-car.js.map +1 -1
- package/dist/src/plugins/plugin-handle-ipld.d.ts +12 -0
- package/dist/src/plugins/plugin-handle-ipld.d.ts.map +1 -0
- package/dist/src/plugins/plugin-handle-ipld.js +83 -0
- package/dist/src/plugins/plugin-handle-ipld.js.map +1 -0
- package/dist/src/plugins/plugin-handle-ipns-record.d.ts +3 -3
- package/dist/src/plugins/plugin-handle-ipns-record.d.ts.map +1 -1
- package/dist/src/plugins/plugin-handle-ipns-record.js +25 -34
- package/dist/src/plugins/plugin-handle-ipns-record.js.map +1 -1
- package/dist/src/plugins/plugin-handle-tar.d.ts +3 -3
- package/dist/src/plugins/plugin-handle-tar.d.ts.map +1 -1
- package/dist/src/plugins/plugin-handle-tar.js +20 -22
- package/dist/src/plugins/plugin-handle-tar.js.map +1 -1
- package/dist/src/plugins/plugin-handle-unixfs.d.ts +14 -0
- package/dist/src/plugins/plugin-handle-unixfs.d.ts.map +1 -0
- package/dist/src/plugins/plugin-handle-unixfs.js +180 -0
- package/dist/src/plugins/plugin-handle-unixfs.js.map +1 -0
- package/dist/src/plugins/types.d.ts +1 -77
- package/dist/src/plugins/types.d.ts.map +1 -1
- package/dist/src/url-resolver.d.ts +29 -11
- package/dist/src/url-resolver.d.ts.map +1 -1
- package/dist/src/url-resolver.js +152 -74
- package/dist/src/url-resolver.js.map +1 -1
- package/dist/src/utils/content-type-parser.d.ts.map +1 -1
- package/dist/src/utils/content-type-parser.js +4 -3
- package/dist/src/utils/content-type-parser.js.map +1 -1
- package/dist/src/utils/content-types.d.ts +26 -0
- package/dist/src/utils/content-types.d.ts.map +1 -0
- package/dist/src/utils/content-types.js +137 -0
- package/dist/src/utils/content-types.js.map +1 -0
- package/dist/src/utils/convert-output.d.ts +17 -0
- package/dist/src/utils/convert-output.d.ts.map +1 -0
- package/dist/src/utils/convert-output.js +176 -0
- package/dist/src/utils/convert-output.js.map +1 -0
- package/dist/src/utils/error-to-response.d.ts +3 -0
- package/dist/src/utils/error-to-response.d.ts.map +1 -0
- package/dist/src/utils/error-to-response.js +40 -0
- package/dist/src/utils/error-to-response.js.map +1 -0
- package/dist/src/utils/get-content-disposition-filename.d.ts +1 -1
- package/dist/src/utils/get-content-disposition-filename.d.ts.map +1 -1
- package/dist/src/utils/get-content-disposition-filename.js +4 -0
- package/dist/src/utils/get-content-disposition-filename.js.map +1 -1
- package/dist/src/utils/get-e-tag.d.ts +20 -15
- package/dist/src/utils/get-e-tag.d.ts.map +1 -1
- package/dist/src/utils/get-e-tag.js +8 -22
- package/dist/src/utils/get-e-tag.js.map +1 -1
- package/dist/src/utils/get-offset-and-length.d.ts +12 -2
- package/dist/src/utils/get-offset-and-length.d.ts.map +1 -1
- package/dist/src/utils/get-offset-and-length.js +63 -21
- package/dist/src/utils/get-offset-and-length.js.map +1 -1
- package/dist/src/utils/get-range-header.d.ts +22 -0
- package/dist/src/utils/get-range-header.d.ts.map +1 -0
- package/dist/src/utils/get-range-header.js +69 -0
- package/dist/src/utils/get-range-header.js.map +1 -0
- package/dist/src/utils/parse-url-string.d.ts +2 -1
- package/dist/src/utils/parse-url-string.d.ts.map +1 -1
- package/dist/src/utils/parse-url-string.js +46 -71
- package/dist/src/utils/parse-url-string.js.map +1 -1
- package/dist/src/utils/resource-to-cache-key.d.ts +3 -3
- package/dist/src/utils/resource-to-cache-key.js +5 -5
- package/dist/src/utils/resource-to-cache-key.js.map +1 -1
- package/dist/src/utils/response-headers.d.ts +4 -14
- package/dist/src/utils/response-headers.d.ts.map +1 -1
- package/dist/src/utils/response-headers.js +36 -36
- package/dist/src/utils/response-headers.js.map +1 -1
- package/dist/src/utils/responses.d.ts +30 -11
- package/dist/src/utils/responses.d.ts.map +1 -1
- package/dist/src/utils/responses.js +146 -39
- package/dist/src/utils/responses.js.map +1 -1
- package/dist/src/verified-fetch.d.ts +16 -15
- package/dist/src/verified-fetch.d.ts.map +1 -1
- package/dist/src/verified-fetch.js +302 -238
- package/dist/src/verified-fetch.js.map +1 -1
- package/dist/typedoc-urls.json +64 -45
- package/package.json +4 -3
- package/src/constants.ts +3 -0
- package/src/index.ts +199 -68
- package/src/plugins/index.ts +0 -6
- package/src/plugins/plugin-base.ts +8 -10
- package/src/plugins/plugin-handle-car.ts +48 -46
- package/src/plugins/plugin-handle-ipld.ts +93 -0
- package/src/plugins/plugin-handle-ipns-record.ts +31 -41
- package/src/plugins/plugin-handle-tar.ts +25 -29
- package/src/plugins/plugin-handle-unixfs.ts +217 -0
- package/src/plugins/types.ts +0 -86
- package/src/url-resolver.ts +197 -83
- package/src/utils/content-type-parser.ts +4 -3
- package/src/utils/content-types.ts +159 -0
- package/src/utils/convert-output.ts +187 -0
- package/src/utils/error-to-response.ts +49 -0
- package/src/utils/get-content-disposition-filename.ts +7 -1
- package/src/utils/get-e-tag.ts +26 -35
- package/src/utils/get-offset-and-length.ts +75 -21
- package/src/utils/get-range-header.ts +107 -0
- package/src/utils/parse-url-string.ts +51 -80
- package/src/utils/resource-to-cache-key.ts +5 -5
- package/src/utils/response-headers.ts +40 -41
- package/src/utils/responses.ts +186 -45
- package/src/verified-fetch.ts +353 -270
- package/dist/src/plugins/plugin-handle-byte-range-context.d.ts +0 -14
- package/dist/src/plugins/plugin-handle-byte-range-context.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-byte-range-context.js +0 -25
- package/dist/src/plugins/plugin-handle-byte-range-context.js.map +0 -1
- package/dist/src/plugins/plugin-handle-cbor.d.ts +0 -17
- package/dist/src/plugins/plugin-handle-cbor.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-cbor.js +0 -94
- package/dist/src/plugins/plugin-handle-cbor.js.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.d.ts +0 -27
- package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.js +0 -279
- package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.js.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-cbor.d.ts +0 -17
- package/dist/src/plugins/plugin-handle-dag-cbor.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-cbor.js +0 -66
- package/dist/src/plugins/plugin-handle-dag-cbor.js.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-pb.d.ts +0 -17
- package/dist/src/plugins/plugin-handle-dag-pb.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-pb.js +0 -209
- package/dist/src/plugins/plugin-handle-dag-pb.js.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-walk.d.ts +0 -21
- package/dist/src/plugins/plugin-handle-dag-walk.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-dag-walk.js +0 -95
- package/dist/src/plugins/plugin-handle-dag-walk.js.map +0 -1
- package/dist/src/plugins/plugin-handle-dir-index-html.d.ts +0 -10
- package/dist/src/plugins/plugin-handle-dir-index-html.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-dir-index-html.js +0 -59
- package/dist/src/plugins/plugin-handle-dir-index-html.js.map +0 -1
- package/dist/src/plugins/plugin-handle-json.d.ts +0 -12
- package/dist/src/plugins/plugin-handle-json.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-json.js +0 -73
- package/dist/src/plugins/plugin-handle-json.js.map +0 -1
- package/dist/src/plugins/plugin-handle-raw.d.ts +0 -9
- package/dist/src/plugins/plugin-handle-raw.d.ts.map +0 -1
- package/dist/src/plugins/plugin-handle-raw.js +0 -92
- package/dist/src/plugins/plugin-handle-raw.js.map +0 -1
- package/dist/src/plugins/plugins.d.ts +0 -6
- package/dist/src/plugins/plugins.d.ts.map +0 -1
- package/dist/src/plugins/plugins.js +0 -6
- package/dist/src/plugins/plugins.js.map +0 -1
- package/dist/src/utils/byte-range-context.d.ts +0 -103
- package/dist/src/utils/byte-range-context.d.ts.map +0 -1
- package/dist/src/utils/byte-range-context.js +0 -504
- package/dist/src/utils/byte-range-context.js.map +0 -1
- package/dist/src/utils/dag-cbor-to-safe-json.d.ts +0 -15
- package/dist/src/utils/dag-cbor-to-safe-json.d.ts.map +0 -1
- package/dist/src/utils/dag-cbor-to-safe-json.js +0 -54
- package/dist/src/utils/dag-cbor-to-safe-json.js.map +0 -1
- package/dist/src/utils/dir-index-html.d.ts +0 -19
- package/dist/src/utils/dir-index-html.d.ts.map +0 -1
- package/dist/src/utils/dir-index-html.js +0 -438
- package/dist/src/utils/dir-index-html.js.map +0 -1
- package/dist/src/utils/get-peer-id-from-string.d.ts +0 -3
- package/dist/src/utils/get-peer-id-from-string.d.ts.map +0 -1
- package/dist/src/utils/get-peer-id-from-string.js +0 -10
- package/dist/src/utils/get-peer-id-from-string.js.map +0 -1
- package/dist/src/utils/get-resolved-accept-header.d.ts +0 -9
- package/dist/src/utils/get-resolved-accept-header.d.ts.map +0 -1
- package/dist/src/utils/get-resolved-accept-header.js +0 -27
- package/dist/src/utils/get-resolved-accept-header.js.map +0 -1
- package/dist/src/utils/get-stream-from-async-iterable.d.ts +0 -9
- package/dist/src/utils/get-stream-from-async-iterable.d.ts.map +0 -1
- package/dist/src/utils/get-stream-from-async-iterable.js +0 -43
- package/dist/src/utils/get-stream-from-async-iterable.js.map +0 -1
- package/dist/src/utils/handle-redirects.d.ts +0 -16
- package/dist/src/utils/handle-redirects.d.ts.map +0 -1
- package/dist/src/utils/handle-redirects.js +0 -84
- package/dist/src/utils/handle-redirects.js.map +0 -1
- package/dist/src/utils/is-accept-explicit.d.ts +0 -15
- package/dist/src/utils/is-accept-explicit.d.ts.map +0 -1
- package/dist/src/utils/is-accept-explicit.js +0 -26
- package/dist/src/utils/is-accept-explicit.js.map +0 -1
- package/dist/src/utils/request-headers.d.ts +0 -13
- package/dist/src/utils/request-headers.d.ts.map +0 -1
- package/dist/src/utils/request-headers.js +0 -63
- package/dist/src/utils/request-headers.js.map +0 -1
- package/dist/src/utils/select-output-type.d.ts +0 -17
- package/dist/src/utils/select-output-type.d.ts.map +0 -1
- package/dist/src/utils/select-output-type.js +0 -153
- package/dist/src/utils/select-output-type.js.map +0 -1
- package/dist/src/utils/tlru.d.ts +0 -15
- package/dist/src/utils/tlru.d.ts.map +0 -1
- package/dist/src/utils/tlru.js +0 -34
- package/dist/src/utils/tlru.js.map +0 -1
- package/dist/src/utils/walk-path.d.ts +0 -27
- package/dist/src/utils/walk-path.d.ts.map +0 -1
- package/dist/src/utils/walk-path.js +0 -45
- package/dist/src/utils/walk-path.js.map +0 -1
- package/src/plugins/plugin-handle-byte-range-context.ts +0 -30
- package/src/plugins/plugin-handle-cbor.ts +0 -107
- package/src/plugins/plugin-handle-dag-cbor-html-preview.ts +0 -295
- package/src/plugins/plugin-handle-dag-cbor.ts +0 -83
- package/src/plugins/plugin-handle-dag-pb.ts +0 -248
- package/src/plugins/plugin-handle-dag-walk.ts +0 -110
- package/src/plugins/plugin-handle-dir-index-html.ts +0 -72
- package/src/plugins/plugin-handle-json.ts +0 -80
- package/src/plugins/plugin-handle-raw.ts +0 -110
- package/src/plugins/plugins.ts +0 -5
- package/src/utils/byte-range-context.ts +0 -597
- package/src/utils/dag-cbor-to-safe-json.ts +0 -63
- package/src/utils/dir-index-html.ts +0 -505
- package/src/utils/get-peer-id-from-string.ts +0 -12
- package/src/utils/get-resolved-accept-header.ts +0 -42
- package/src/utils/get-stream-from-async-iterable.ts +0 -49
- package/src/utils/handle-redirects.ts +0 -109
- package/src/utils/is-accept-explicit.ts +0 -38
- package/src/utils/request-headers.ts +0 -65
- package/src/utils/select-output-type.ts +0 -175
- package/src/utils/tlru.ts +0 -42
- package/src/utils/walk-path.ts +0 -69
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { InvalidRangeError } from '../errors.ts'
|
|
2
|
+
import { badRequestResponse, notSatisfiableResponse } from './responses.ts'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Range
|
|
6
|
+
*/
|
|
7
|
+
export interface Range {
|
|
8
|
+
/**
|
|
9
|
+
* Where the range starts, zero indexed
|
|
10
|
+
*/
|
|
11
|
+
start?: number
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Where the range ends, inclusive
|
|
15
|
+
*/
|
|
16
|
+
end?: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Range
|
|
21
|
+
*/
|
|
22
|
+
export interface RangeHeader {
|
|
23
|
+
multipartBoundary: string
|
|
24
|
+
ranges: Range[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function parseValue (val?: string): number | undefined {
|
|
28
|
+
if (val == null || val === '') {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const num = Number(val)
|
|
33
|
+
|
|
34
|
+
if (isNaN(num)) {
|
|
35
|
+
throw new InvalidRangeError(`Invalid range specification: could not parse "${num}" as number`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return num
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getByteRangeFromHeader (rangeHeader?: string): Range[] {
|
|
42
|
+
if (rangeHeader == null || rangeHeader === '') {
|
|
43
|
+
return []
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Range: bytes=<start>-<end> | bytes=<start2>- | bytes=-<end2> | bytes=<start1>-<end1>,<start2>-<end2>,...
|
|
48
|
+
*/
|
|
49
|
+
if (!rangeHeader.startsWith('bytes=')) {
|
|
50
|
+
throw new InvalidRangeError('Invalid range request')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const rangesStr = rangeHeader.substring(6) // Remove "bytes=" prefix
|
|
54
|
+
const rangeParts = rangesStr.split(',').map(part => part.trim())
|
|
55
|
+
const ranges: Range[] = []
|
|
56
|
+
|
|
57
|
+
for (const part of rangeParts) {
|
|
58
|
+
const match = part.match(/^(?<start>\d+)?-(?<end>\d+)?$/)
|
|
59
|
+
|
|
60
|
+
if (match?.groups == null) {
|
|
61
|
+
throw new InvalidRangeError(`Invalid range specification: ${part}`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (part.startsWith('-')) {
|
|
65
|
+
ranges.push({
|
|
66
|
+
end: parseValue(part)
|
|
67
|
+
})
|
|
68
|
+
} else {
|
|
69
|
+
const { start, end } = match.groups
|
|
70
|
+
|
|
71
|
+
ranges.push({
|
|
72
|
+
start: parseValue(start),
|
|
73
|
+
end: parseValue(end)
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return ranges
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function getRangeHeader (resource: string, headers: Headers): RangeHeader | undefined | Response {
|
|
82
|
+
const header = headers.get('range')
|
|
83
|
+
|
|
84
|
+
// not a range request
|
|
85
|
+
if (header == null) {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const ranges = getByteRangeFromHeader(header)
|
|
91
|
+
|
|
92
|
+
if (ranges.length === 0) {
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
multipartBoundary: `multipart_byteranges_${Math.floor(Math.random() * 1_000_000_000)}`,
|
|
98
|
+
ranges
|
|
99
|
+
}
|
|
100
|
+
} catch (e: any) {
|
|
101
|
+
if (e.name === 'InvalidRangeError') {
|
|
102
|
+
return notSatisfiableResponse(resource)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return badRequestResponse(resource, e)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { InvalidParametersError } from '@libp2p/interface'
|
|
2
|
+
import { peerIdFromCID, peerIdFromString } from '@libp2p/peer-id'
|
|
3
|
+
import { CID } from 'multiformats/cid'
|
|
2
4
|
import { decodeDNSLinkLabel, isInlinedDnsLink } from './dnslink-label.ts'
|
|
3
5
|
import { ipfsPathToUrl, ipfsUrlToUrl } from './ipfs-path-to-url.ts'
|
|
4
6
|
|
|
@@ -7,7 +9,8 @@ interface SubdomainMatchGroups {
|
|
|
7
9
|
cidOrPeerIdOrDnsLink: string
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
const SUBDOMAIN_GATEWAY_REGEX = /^(?<cidOrPeerIdOrDnsLink>[^/?]+)\.(?<protocol>ip[fn]s)\.([^/?]+)$/
|
|
12
|
+
export const SUBDOMAIN_GATEWAY_REGEX = /^(?<cidOrPeerIdOrDnsLink>[^/?]+)\.(?<protocol>ip[fn]s)\.([^/?]+)$/
|
|
13
|
+
const CODEC_LIBP2P_KEY = 0x72
|
|
11
14
|
|
|
12
15
|
function matchSubdomainGroupsGuard (groups?: null | { [key in string]: string; } | SubdomainMatchGroups): groups is SubdomainMatchGroups {
|
|
13
16
|
const protocol = groups?.protocol
|
|
@@ -34,40 +37,6 @@ export interface ParsedURL {
|
|
|
34
37
|
fragment: string
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
function toQuery (query?: URLSearchParams): Record<string, any> {
|
|
38
|
-
if (query == null) {
|
|
39
|
-
return {}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const output: Record<string, any> = {}
|
|
43
|
-
|
|
44
|
-
for (const [key, value] of query.entries()) {
|
|
45
|
-
output[key] = value
|
|
46
|
-
|
|
47
|
-
if (value === 'true') {
|
|
48
|
-
output[key] = true
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (value === 'false') {
|
|
52
|
-
output[key] = false
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return output
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function stripLeadingHash (pathname: string): string {
|
|
60
|
-
return stripLeading(pathname, '#')
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function stripLeading (str: string, char: string): string {
|
|
64
|
-
while (str.startsWith(char)) {
|
|
65
|
-
str = str.substring(1)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return str
|
|
69
|
-
}
|
|
70
|
-
|
|
71
40
|
/**
|
|
72
41
|
* If the caller has passed a case-sensitive identifier (like a base58btc
|
|
73
42
|
* encoded CID or PeerId) in a case-insensitive location (like a subdomain),
|
|
@@ -83,7 +52,11 @@ function findOriginalCidOrPeer (needle: string, haystack: string): string {
|
|
|
83
52
|
return haystack.substring(start, start + needle.length)
|
|
84
53
|
}
|
|
85
54
|
|
|
86
|
-
function
|
|
55
|
+
function stringToUrl (urlString: string | URL): URL {
|
|
56
|
+
if (urlString instanceof URL) {
|
|
57
|
+
return urlString
|
|
58
|
+
}
|
|
59
|
+
|
|
87
60
|
// turn IPFS/IPNS path into gateway URL string
|
|
88
61
|
if (urlString.startsWith('/ipfs/') || urlString.startsWith('/ipns/')) {
|
|
89
62
|
urlString = ipfsPathToUrl(urlString)
|
|
@@ -101,21 +74,9 @@ function toUrl (urlString: string): URL {
|
|
|
101
74
|
throw new InvalidParametersError(`Invalid URL: ${urlString}`)
|
|
102
75
|
}
|
|
103
76
|
|
|
104
|
-
|
|
105
|
-
* Accepts the following url strings:
|
|
106
|
-
*
|
|
107
|
-
* - /ipfs/Qmfoo/path
|
|
108
|
-
* - /ipns/Qmfoo/path
|
|
109
|
-
* - ipfs://cid/path
|
|
110
|
-
* - ipns://name/path
|
|
111
|
-
* - http://cid.ipfs.example.com/path
|
|
112
|
-
* - http://name.ipns.example.com/path
|
|
113
|
-
* - http://example.com/ipfs/cid/path
|
|
114
|
-
* - http://example.com/ipns/name/path
|
|
115
|
-
*/
|
|
116
|
-
export function parseURLString (urlString: string): ParsedURL {
|
|
77
|
+
function toURL (urlString: string): URL {
|
|
117
78
|
// validate url
|
|
118
|
-
const url =
|
|
79
|
+
const url = stringToUrl(urlString)
|
|
119
80
|
|
|
120
81
|
// test for subdomain gateway URL
|
|
121
82
|
const subdomainMatch = url.hostname.match(SUBDOMAIN_GATEWAY_REGEX)
|
|
@@ -136,16 +97,7 @@ export function parseURLString (urlString: string): ParsedURL {
|
|
|
136
97
|
// input while also maintaining a sane canonical URL for the resource. Phew.
|
|
137
98
|
const wat = new URL(`not-${urlString}`)
|
|
138
99
|
|
|
139
|
-
return {
|
|
140
|
-
url: new URL(`${groups.protocol}://${cidOrPeerIdOrDnsLink}${wat.pathname}${url.search}${url.hash}`),
|
|
141
|
-
protocol: groups.protocol,
|
|
142
|
-
cidOrPeerIdOrDnsLink,
|
|
143
|
-
path: url.pathname.split('/')
|
|
144
|
-
.filter(str => str !== '')
|
|
145
|
-
.map(str => decodeURIComponent(str)),
|
|
146
|
-
query: toQuery(url.searchParams),
|
|
147
|
-
fragment: stripLeadingHash(url.hash)
|
|
148
|
-
}
|
|
100
|
+
return new URL(`${groups.protocol}://${cidOrPeerIdOrDnsLink}${wat.pathname}${url.search}${url.hash}`)
|
|
149
101
|
}
|
|
150
102
|
|
|
151
103
|
// test for IPFS path gateway URL
|
|
@@ -157,16 +109,7 @@ export function parseURLString (urlString: string): ParsedURL {
|
|
|
157
109
|
throw new InvalidParametersError(`Path gateway URL ${urlString} had no CID`)
|
|
158
110
|
}
|
|
159
111
|
|
|
160
|
-
return {
|
|
161
|
-
url: new URL(`ipfs://${cid}${url.pathname.replace(`/ipfs/${cid}`, '')}${url.search}${url.hash}`),
|
|
162
|
-
protocol: 'ipfs',
|
|
163
|
-
cidOrPeerIdOrDnsLink: cid,
|
|
164
|
-
path: parts
|
|
165
|
-
.filter(str => str !== '')
|
|
166
|
-
.map(str => decodeURIComponent(str)),
|
|
167
|
-
query: toQuery(url.searchParams),
|
|
168
|
-
fragment: stripLeadingHash(url.hash)
|
|
169
|
-
}
|
|
112
|
+
return new URL(`ipfs://${cid}${url.pathname.replace(`/ipfs/${cid}`, '')}${url.search}${url.hash}`)
|
|
170
113
|
}
|
|
171
114
|
|
|
172
115
|
// test for IPNS path gateway URL
|
|
@@ -178,17 +121,45 @@ export function parseURLString (urlString: string): ParsedURL {
|
|
|
178
121
|
throw new InvalidParametersError(`Path gateway URL ${urlString} had no name`)
|
|
179
122
|
}
|
|
180
123
|
|
|
181
|
-
return {
|
|
182
|
-
url: new URL(`ipns://${name}${url.pathname.replace(`/ipns/${name}`, '')}${url.search}${url.hash}`),
|
|
183
|
-
protocol: 'ipns',
|
|
184
|
-
cidOrPeerIdOrDnsLink: name,
|
|
185
|
-
path: parts
|
|
186
|
-
.filter(str => str !== '')
|
|
187
|
-
.map(str => decodeURIComponent(str)),
|
|
188
|
-
query: toQuery(url.searchParams),
|
|
189
|
-
fragment: stripLeadingHash(url.hash)
|
|
190
|
-
}
|
|
124
|
+
return new URL(`ipns://${name}${url.pathname.replace(`/ipns/${name}`, '')}${url.search}${url.hash}`)
|
|
191
125
|
}
|
|
192
126
|
|
|
193
127
|
throw new TypeError(`Invalid URL: ${urlString}, please use ipfs://, ipns://, or gateway URLs only`)
|
|
194
128
|
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Accepts the following url strings:
|
|
132
|
+
*
|
|
133
|
+
* - /ipfs/Qmfoo/path
|
|
134
|
+
* - /ipns/Qmfoo/path
|
|
135
|
+
* - ipfs://cid/path
|
|
136
|
+
* - ipns://name/path
|
|
137
|
+
* - http://cid.ipfs.example.com/path
|
|
138
|
+
* - http://name.ipns.example.com/path
|
|
139
|
+
* - http://example.com/ipfs/cid/path
|
|
140
|
+
* - http://example.com/ipns/name/path
|
|
141
|
+
*/
|
|
142
|
+
export function parseURLString (urlString: string): URL {
|
|
143
|
+
// validate url
|
|
144
|
+
const url = toURL(urlString)
|
|
145
|
+
|
|
146
|
+
// treat IPNS keys that do not parse as PeerIds as DNSLink
|
|
147
|
+
if (url.protocol === 'ipns:') {
|
|
148
|
+
try {
|
|
149
|
+
peerIdFromString(url.hostname)
|
|
150
|
+
} catch {
|
|
151
|
+
url.protocol = 'dnslink:'
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (url.protocol === 'ipfs:') {
|
|
156
|
+
const cid = CID.parse(url.hostname)
|
|
157
|
+
|
|
158
|
+
// special case - peer id encoded as a CID
|
|
159
|
+
if (cid.code === CODEC_LIBP2P_KEY) {
|
|
160
|
+
return new URL(`ipns://${peerIdFromCID(cid)}${url.pathname}${url.search}${url.hash}`)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return url
|
|
165
|
+
}
|
|
@@ -8,9 +8,9 @@ import { parseURLString } from './parse-url-string.js'
|
|
|
8
8
|
* E.g.
|
|
9
9
|
*
|
|
10
10
|
* - Qmfoo -> /ipfs/Qmfoo
|
|
11
|
-
* - https://Qmfoo.ipfs.gateway.org ->
|
|
12
|
-
* - https://gateway.org/ipfs/Qmfoo ->
|
|
13
|
-
* - https://gateway.org/ipfs/Qmfoo/bar.txt ->
|
|
11
|
+
* - https://Qmfoo.ipfs.gateway.org -> ipfs://Qmfoo
|
|
12
|
+
* - https://gateway.org/ipfs/Qmfoo -> ipfs://Qmfoo
|
|
13
|
+
* - https://gateway.org/ipfs/Qmfoo/bar.txt -> ipfs://Qmfoo
|
|
14
14
|
* - etc
|
|
15
15
|
*/
|
|
16
16
|
export function resourceToSessionCacheKey (url: string | CID): string {
|
|
@@ -24,7 +24,7 @@ export function resourceToSessionCacheKey (url: string | CID): string {
|
|
|
24
24
|
return `ipfs://${CID.parse(url.toString())}`
|
|
25
25
|
} catch {}
|
|
26
26
|
|
|
27
|
-
const { protocol,
|
|
27
|
+
const { protocol, host } = parseURLString(url.toString())
|
|
28
28
|
|
|
29
|
-
return `${protocol}
|
|
29
|
+
return `${protocol}//${host}`
|
|
30
30
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { InvalidRangeError } from '../errors.js'
|
|
2
|
-
import type { CID } from 'multiformats/cid'
|
|
3
2
|
|
|
4
3
|
interface CacheControlHeaderOptions {
|
|
5
4
|
/**
|
|
@@ -24,8 +23,10 @@ export function setCacheControlHeader ({ ttl, protocol, response }: CacheControl
|
|
|
24
23
|
// don't set the header if it's already set by a plugin
|
|
25
24
|
return
|
|
26
25
|
}
|
|
26
|
+
|
|
27
27
|
let headerValue: string
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
if (protocol === 'ipfs:') {
|
|
29
30
|
headerValue = 'public, max-age=29030400, immutable'
|
|
30
31
|
} else if (ttl == null) {
|
|
31
32
|
/**
|
|
@@ -42,59 +43,57 @@ export function setCacheControlHeader ({ ttl, protocol, response }: CacheControl
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
/**
|
|
45
|
-
* This function returns the value of the `Content-Range` header for a given
|
|
46
|
+
* This function returns the value of the `Content-Range` header for a given
|
|
47
|
+
* range.
|
|
48
|
+
*
|
|
46
49
|
* If you know the total size of the body, pass it as `byteSize`
|
|
47
50
|
*
|
|
48
51
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
|
|
49
52
|
*/
|
|
50
|
-
export function getContentRangeHeader (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if ((byteEnd ?? 0) >= (byteSize ?? Infinity)) {
|
|
54
|
-
throw new InvalidRangeError('Invalid range: Range-end index is greater than or equal to the size of the file.')
|
|
55
|
-
}
|
|
56
|
-
if ((byteStart ?? 0) >= (byteSize ?? Infinity)) {
|
|
57
|
-
throw new InvalidRangeError('Invalid range: Range-start index is greater than or equal to the size of the file.')
|
|
53
|
+
export function getContentRangeHeader (byteSize: number | bigint | string, byteStart?: number | bigint | string, byteEnd?: number | bigint | string): string {
|
|
54
|
+
if (byteStart != null) {
|
|
55
|
+
byteStart = BigInt(byteStart)
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
if (byteSize == null) {
|
|
63
|
-
return `bytes */${total}`
|
|
64
|
-
}
|
|
65
|
-
return `bytes ${byteStart}-${byteSize - 1}/${byteSize}`
|
|
58
|
+
if (byteEnd != null) {
|
|
59
|
+
byteEnd = BigInt(byteEnd)
|
|
66
60
|
}
|
|
67
61
|
|
|
68
|
-
if
|
|
69
|
-
|
|
70
|
-
if (byteSize == null) {
|
|
71
|
-
return `bytes */${total}`
|
|
72
|
-
}
|
|
73
|
-
const end = byteSize - 1
|
|
74
|
-
const start = end - byteEnd + 1
|
|
62
|
+
// if we don't know the total size, we should use *
|
|
63
|
+
const total = BigInt(byteSize)
|
|
75
64
|
|
|
76
|
-
|
|
65
|
+
// validate start/end are not outside total size
|
|
66
|
+
if ((byteEnd ?? 0n) >= total) {
|
|
67
|
+
throw new InvalidRangeError('Invalid range: Range-end index is greater than or equal to the size of the file.')
|
|
77
68
|
}
|
|
78
69
|
|
|
79
|
-
if (byteStart
|
|
80
|
-
|
|
81
|
-
return `bytes */${total}`
|
|
70
|
+
if ((byteStart ?? 0n) >= total) {
|
|
71
|
+
throw new InvalidRangeError('Invalid range: Range-start index is greater than or equal to the size of the file.')
|
|
82
72
|
}
|
|
83
73
|
|
|
84
|
-
|
|
85
|
-
}
|
|
74
|
+
let range = '*'
|
|
86
75
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
76
|
+
if (byteStart == null) {
|
|
77
|
+
if (byteEnd != null) {
|
|
78
|
+
if (byteEnd < 0n) {
|
|
79
|
+
range = `${total + byteEnd}-${total - 1n}`
|
|
80
|
+
} else {
|
|
81
|
+
range = `0-${byteEnd}`
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
if (byteEnd == null) {
|
|
86
|
+
let end = '*'
|
|
87
|
+
|
|
88
|
+
if (byteSize != null) {
|
|
89
|
+
end = `${total - 1n}`
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
range = `${byteStart}-${end}`
|
|
93
|
+
} else {
|
|
94
|
+
range = `${byteStart}-${byteEnd}`
|
|
95
|
+
}
|
|
95
96
|
}
|
|
96
|
-
}
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
return ipfsRoots.map(cid => cid.toV1().toString()).join(',')
|
|
98
|
+
return `bytes ${range}/${total}`
|
|
100
99
|
}
|