@helia/verified-fetch 2.3.1 → 2.4.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 +8 -0
- package/dist/index.min.js +21 -24
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/types.d.ts +4 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/parse-resource.d.ts +2 -1
- package/dist/src/utils/parse-resource.d.ts.map +1 -1
- package/dist/src/utils/parse-resource.js +4 -3
- package/dist/src/utils/parse-resource.js.map +1 -1
- package/dist/src/utils/parse-url-string.d.ts +8 -3
- package/dist/src/utils/parse-url-string.d.ts.map +1 -1
- package/dist/src/utils/parse-url-string.js +30 -4
- package/dist/src/utils/parse-url-string.js.map +1 -1
- package/dist/src/utils/server-timing.d.ts +13 -0
- package/dist/src/utils/server-timing.d.ts.map +1 -0
- package/dist/src/utils/server-timing.js +19 -0
- package/dist/src/utils/server-timing.js.map +1 -0
- package/dist/src/verified-fetch.d.ts +9 -0
- package/dist/src/verified-fetch.d.ts.map +1 -1
- package/dist/src/verified-fetch.js +48 -18
- package/dist/src/verified-fetch.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +24 -0
- package/src/types.ts +5 -0
- package/src/utils/parse-resource.ts +5 -4
- package/src/utils/parse-url-string.ts +38 -7
- package/src/utils/server-timing.ts +37 -0
- package/src/verified-fetch.ts +56 -18
package/dist/src/index.d.ts
CHANGED
|
@@ -604,6 +604,14 @@
|
|
|
604
604
|
* * https://specs.ipfs.tech/http-gateways/trustless-gateway/#response-headers
|
|
605
605
|
* * https://specs.ipfs.tech/http-gateways/subdomain-gateway/#response-headers
|
|
606
606
|
*
|
|
607
|
+
* #### Server Timing headers
|
|
608
|
+
*
|
|
609
|
+
* By default, we do not include [Server Timing](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Server_timing) headers in responses. If you want to include them, you can pass an
|
|
610
|
+
* `withServerTiming` option to the `createVerifiedFetch` function to include them in all future responses. You can
|
|
611
|
+
* also pass the `withServerTiming` option to each fetch call to include them only for that specific response.
|
|
612
|
+
*
|
|
613
|
+
* See PR where this was added, https://github.com/ipfs/helia-verified-fetch/pull/164, for more information.
|
|
614
|
+
*
|
|
607
615
|
* ### Possible Scenarios that could cause confusion
|
|
608
616
|
*
|
|
609
617
|
* #### Attempting to fetch the CID for content that does not make sense
|
|
@@ -730,6 +738,13 @@ export interface CreateVerifiedFetchOptions {
|
|
|
730
738
|
* @default 60000
|
|
731
739
|
*/
|
|
732
740
|
sessionTTLms?: number;
|
|
741
|
+
/**
|
|
742
|
+
* Whether to include server-timing headers in responses. This option can be overridden on a per-request basis.
|
|
743
|
+
*
|
|
744
|
+
* @default false
|
|
745
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
|
|
746
|
+
*/
|
|
747
|
+
withServerTiming?: boolean;
|
|
733
748
|
}
|
|
734
749
|
export type { ContentTypeParser } from './types.js';
|
|
735
750
|
export type BubbledProgressEvents = ExporterProgressEvents | GetBlockProgressEvents | ResolveDNSLinkProgressEvents;
|
|
@@ -780,6 +795,13 @@ export interface VerifiedFetchInit extends RequestInit, ProgressOptions<BubbledP
|
|
|
780
795
|
* @default false
|
|
781
796
|
*/
|
|
782
797
|
allowInsecure?: boolean;
|
|
798
|
+
/**
|
|
799
|
+
* Whether to include server-timing headers in the response for an individual request.
|
|
800
|
+
*
|
|
801
|
+
* @default false
|
|
802
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
|
|
803
|
+
*/
|
|
804
|
+
withServerTiming?: boolean;
|
|
783
805
|
}
|
|
784
806
|
/**
|
|
785
807
|
* Create and return a Helia node
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -604,6 +604,14 @@
|
|
|
604
604
|
* * https://specs.ipfs.tech/http-gateways/trustless-gateway/#response-headers
|
|
605
605
|
* * https://specs.ipfs.tech/http-gateways/subdomain-gateway/#response-headers
|
|
606
606
|
*
|
|
607
|
+
* #### Server Timing headers
|
|
608
|
+
*
|
|
609
|
+
* By default, we do not include [Server Timing](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Server_timing) headers in responses. If you want to include them, you can pass an
|
|
610
|
+
* `withServerTiming` option to the `createVerifiedFetch` function to include them in all future responses. You can
|
|
611
|
+
* also pass the `withServerTiming` option to each fetch call to include them only for that specific response.
|
|
612
|
+
*
|
|
613
|
+
* See PR where this was added, https://github.com/ipfs/helia-verified-fetch/pull/164, for more information.
|
|
614
|
+
*
|
|
607
615
|
* ### Possible Scenarios that could cause confusion
|
|
608
616
|
*
|
|
609
617
|
* #### Attempting to fetch the CID for content that does not make sense
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -22,6 +22,10 @@ export interface FetchHandlerFunctionArg {
|
|
|
22
22
|
* The originally requested resource
|
|
23
23
|
*/
|
|
24
24
|
resource: string;
|
|
25
|
+
/**
|
|
26
|
+
* Whether to include server-timing headers in the response.
|
|
27
|
+
*/
|
|
28
|
+
withServerTiming: boolean;
|
|
25
29
|
}
|
|
26
30
|
/**
|
|
27
31
|
* A ContentTypeParser attempts to return the mime type of a given file. It
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;AAEtH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;AAEhG,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,CAAA;IAEZ;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAA;IAEhB,OAAO,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAA;IAE1D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;AAEtH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;AAEhG,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,CAAA;IAEZ;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAA;IAEhB,OAAO,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAA;IAE1D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAA;CACzF"}
|
|
@@ -7,11 +7,12 @@ export interface ParseResourceComponents {
|
|
|
7
7
|
logger: ComponentLogger;
|
|
8
8
|
}
|
|
9
9
|
export interface ParseResourceOptions extends ParseUrlStringOptions {
|
|
10
|
+
withServerTiming?: boolean;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* Handles the different use cases for the `resource` argument.
|
|
13
14
|
* The resource can represent an IPFS path, IPNS path, or CID.
|
|
14
15
|
* If the resource represents an IPNS path, we need to resolve it to a CID.
|
|
15
16
|
*/
|
|
16
|
-
export declare function parseResource(resource: Resource, { ipns, logger }: ParseResourceComponents, options?: ParseResourceOptions): Promise<ParsedUrlStringResults>;
|
|
17
|
+
export declare function parseResource(resource: Resource, { ipns, logger }: ParseResourceComponents, { withServerTiming, ...options }?: ParseResourceOptions): Promise<ParsedUrlStringResults>;
|
|
17
18
|
//# sourceMappingURL=parse-resource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-resource.d.ts","sourceRoot":"","sources":["../../../src/utils/parse-resource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC1F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;
|
|
1
|
+
{"version":3,"file":"parse-resource.d.ts","sourceRoot":"","sources":["../../../src/utils/parse-resource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC1F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IACjE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AACD;;;;GAIG;AACH,wBAAsB,aAAa,CAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,uBAAuB,EAAE,EAAE,gBAAwB,EAAE,GAAG,OAAO,EAAE,GAAE,oBAAkD,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAqBjO"}
|
|
@@ -5,9 +5,9 @@ import { parseUrlString } from './parse-url-string.js';
|
|
|
5
5
|
* The resource can represent an IPFS path, IPNS path, or CID.
|
|
6
6
|
* If the resource represents an IPNS path, we need to resolve it to a CID.
|
|
7
7
|
*/
|
|
8
|
-
export async function parseResource(resource, { ipns, logger }, options) {
|
|
8
|
+
export async function parseResource(resource, { ipns, logger }, { withServerTiming = false, ...options } = { withServerTiming: false }) {
|
|
9
9
|
if (typeof resource === 'string') {
|
|
10
|
-
return parseUrlString({ urlString: resource, ipns, logger }, options);
|
|
10
|
+
return parseUrlString({ urlString: resource, ipns, logger, withServerTiming }, options);
|
|
11
11
|
}
|
|
12
12
|
const cid = CID.asCID(resource);
|
|
13
13
|
if (cid != null) {
|
|
@@ -18,7 +18,8 @@ export async function parseResource(resource, { ipns, logger }, options) {
|
|
|
18
18
|
path: '',
|
|
19
19
|
query: {},
|
|
20
20
|
ipfsPath: `/ipfs/${cid.toString()}`,
|
|
21
|
-
ttl: 29030400 // 1 year for ipfs content
|
|
21
|
+
ttl: 29030400, // 1 year for ipfs content
|
|
22
|
+
serverTimings: []
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
throw new TypeError(`Invalid resource. Cannot determine CID from resource: ${resource}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-resource.js","sourceRoot":"","sources":["../../../src/utils/parse-resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AActD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAE,QAAkB,EAAE,EAAE,IAAI,EAAE,MAAM,EAA2B,EAAE,
|
|
1
|
+
{"version":3,"file":"parse-resource.js","sourceRoot":"","sources":["../../../src/utils/parse-resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AActD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAE,QAAkB,EAAE,EAAE,IAAI,EAAE,MAAM,EAA2B,EAAE,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,OAAO,KAA2B,EAAE,gBAAgB,EAAE,KAAK,EAAE;IAC9L,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,OAAO,CAAC,CAAA;IACzF,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAE/B,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,gBAAgB;QAChB,OAAO;YACL,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,SAAS,GAAG,CAAC,QAAQ,EAAE,EAAE;YACnC,GAAG,EAAE,QAAQ,EAAE,0BAA0B;YACzC,aAAa,EAAE,EAAE;SACe,CAAA;IACpC,CAAC;IAED,MAAM,IAAI,SAAS,CAAC,yDAAyD,QAAQ,EAAE,CAAC,CAAA;AAC1F,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ServerTimingResult } from './server-timing.js';
|
|
1
2
|
import type { RequestFormatShorthand } from '../types.js';
|
|
2
3
|
import type { IPNS, IPNSRoutingEvents, ResolveDNSLinkProgressEvents, ResolveProgressEvents, ResolveResult } from '@helia/ipns';
|
|
3
4
|
import type { AbortOptions, ComponentLogger } from '@libp2p/interface';
|
|
@@ -6,6 +7,7 @@ export interface ParseUrlStringInput {
|
|
|
6
7
|
urlString: string;
|
|
7
8
|
ipns: IPNS;
|
|
8
9
|
logger: ComponentLogger;
|
|
10
|
+
withServerTiming?: boolean;
|
|
9
11
|
}
|
|
10
12
|
export interface ParseUrlStringOptions extends ProgressOptions<ResolveProgressEvents | IPNSRoutingEvents | ResolveDNSLinkProgressEvents>, AbortOptions {
|
|
11
13
|
}
|
|
@@ -14,7 +16,7 @@ export interface ParsedUrlQuery extends Record<string, string | unknown> {
|
|
|
14
16
|
download?: boolean;
|
|
15
17
|
filename?: string;
|
|
16
18
|
}
|
|
17
|
-
interface
|
|
19
|
+
export interface ParsedUrlStringResults extends ResolveResult {
|
|
18
20
|
protocol: 'ipfs' | 'ipns';
|
|
19
21
|
query: ParsedUrlQuery;
|
|
20
22
|
/**
|
|
@@ -30,8 +32,11 @@ interface ParsedUrlStringResultsBase extends ResolveResult {
|
|
|
30
32
|
* seconds as a number
|
|
31
33
|
*/
|
|
32
34
|
ttl?: number;
|
|
35
|
+
/**
|
|
36
|
+
* serverTiming items
|
|
37
|
+
*/
|
|
38
|
+
serverTimings: Array<ServerTimingResult<any>>;
|
|
33
39
|
}
|
|
34
|
-
export type ParsedUrlStringResults = ParsedUrlStringResultsBase;
|
|
35
40
|
interface MatchUrlGroups {
|
|
36
41
|
protocol: 'ipfs' | 'ipns';
|
|
37
42
|
cidOrPeerIdOrDnsLink: string;
|
|
@@ -48,6 +53,6 @@ export declare function matchURLString(urlString: string): MatchUrlGroups;
|
|
|
48
53
|
*
|
|
49
54
|
* @todo we need to break out each step of this function (cid parsing, ipns resolving, dnslink resolving) into separate functions and then remove the eslint-disable comment
|
|
50
55
|
*/
|
|
51
|
-
export declare function parseUrlString({ urlString, ipns, logger }: ParseUrlStringInput, options?: ParseUrlStringOptions): Promise<ParsedUrlStringResults>;
|
|
56
|
+
export declare function parseUrlString({ urlString, ipns, logger, withServerTiming }: ParseUrlStringInput, options?: ParseUrlStringOptions): Promise<ParsedUrlStringResults>;
|
|
52
57
|
export {};
|
|
53
58
|
//# sourceMappingURL=parse-url-string.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-url-string.d.ts","sourceRoot":"","sources":["../../../src/utils/parse-url-string.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parse-url-string.d.ts","sourceRoot":"","sources":["../../../src/utils/parse-url-string.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,KAAK,EAAwB,IAAI,EAAqB,iBAAiB,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACvK,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAU,MAAM,mBAAmB,CAAA;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAItD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,EAAE,eAAe,CAAA;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AACD,MAAM,WAAW,qBAAsB,SAAQ,eAAe,CAAC,qBAAqB,GAAG,iBAAiB,GAAG,4BAA4B,CAAC,EAAE,YAAY;CAErJ;AAED,MAAM,WAAW,cAAe,SAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACtE,MAAM,CAAC,EAAE,sBAAsB,CAAA;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,KAAK,EAAE,cAAc,CAAA;IAErB;;;;;;;OAOG;IACH,QAAQ,EAAE,MAAM,CAAA;IAEhB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,aAAa,EAAE,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAA;CAC9C;AAOD,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAgBD,wBAAgB,cAAc,CAAE,SAAS,EAAE,MAAM,GAAG,cAAc,CAUjE;AAsDD;;;;;;;;GAQG;AAEH,wBAAsB,cAAc,CAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAwB,EAAE,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAkJlL"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CID } from 'multiformats/cid';
|
|
2
2
|
import { getPeerIdFromString } from './get-peer-id-from-string.js';
|
|
3
|
+
import { serverTiming } from './server-timing.js';
|
|
3
4
|
import { TLRU } from './tlru.js';
|
|
4
5
|
const ipnsCache = new TLRU(1000);
|
|
5
6
|
const URL_REGEX = /^(?<protocol>ip[fn]s):\/\/(?<cidOrPeerIdOrDnsLink>[^/?]+)\/?(?<path>[^?]*)\??(?<queryString>.*)$/;
|
|
@@ -86,13 +87,14 @@ function dnsLinkLabelDecoder(linkLabel) {
|
|
|
86
87
|
* @todo we need to break out each step of this function (cid parsing, ipns resolving, dnslink resolving) into separate functions and then remove the eslint-disable comment
|
|
87
88
|
*/
|
|
88
89
|
// eslint-disable-next-line complexity
|
|
89
|
-
export async function parseUrlString({ urlString, ipns, logger }, options) {
|
|
90
|
+
export async function parseUrlString({ urlString, ipns, logger, withServerTiming = false }, options) {
|
|
90
91
|
const log = logger.forComponent('helia:verified-fetch:parse-url-string');
|
|
91
92
|
const { protocol, cidOrPeerIdOrDnsLink, path: urlPath, queryString } = matchURLString(urlString);
|
|
92
93
|
let cid;
|
|
93
94
|
let resolvedPath;
|
|
94
95
|
const errors = [];
|
|
95
96
|
let resolveResult;
|
|
97
|
+
const serverTimings = [];
|
|
96
98
|
if (protocol === 'ipfs') {
|
|
97
99
|
try {
|
|
98
100
|
cid = CID.parse(cidOrPeerIdOrDnsLink);
|
|
@@ -122,7 +124,18 @@ export async function parseUrlString({ urlString, ipns, logger }, options) {
|
|
|
122
124
|
if (peerId.publicKey == null) {
|
|
123
125
|
throw new TypeError('cidOrPeerIdOrDnsLink contains no public key');
|
|
124
126
|
}
|
|
125
|
-
|
|
127
|
+
if (withServerTiming) {
|
|
128
|
+
const resolveResultWithServerTiming = await serverTiming('ipns.resolve', `Resolve IPNS name ${cidOrPeerIdOrDnsLink}`, ipns.resolve.bind(null, peerId.publicKey, options));
|
|
129
|
+
serverTimings.push(resolveResultWithServerTiming);
|
|
130
|
+
// eslint-disable-next-line max-depth
|
|
131
|
+
if (resolveResultWithServerTiming.error != null) {
|
|
132
|
+
throw resolveResultWithServerTiming.error;
|
|
133
|
+
}
|
|
134
|
+
resolveResult = resolveResultWithServerTiming.result;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
resolveResult = await ipns.resolve(peerId.publicKey, options);
|
|
138
|
+
}
|
|
126
139
|
cid = resolveResult?.cid;
|
|
127
140
|
resolvedPath = resolveResult?.path;
|
|
128
141
|
log.trace('resolved %s to %c', cidOrPeerIdOrDnsLink, cid);
|
|
@@ -147,7 +160,19 @@ export async function parseUrlString({ urlString, ipns, logger }, options) {
|
|
|
147
160
|
}
|
|
148
161
|
log.trace('Attempting to resolve DNSLink for %s', decodedDnsLinkLabel);
|
|
149
162
|
try {
|
|
150
|
-
|
|
163
|
+
// eslint-disable-next-line max-depth
|
|
164
|
+
if (withServerTiming) {
|
|
165
|
+
const resolveResultWithServerTiming = await serverTiming('ipns.resolveDNSLink', `Resolve DNSLink ${decodedDnsLinkLabel}`, ipns.resolveDNSLink.bind(ipns, decodedDnsLinkLabel, options));
|
|
166
|
+
serverTimings.push(resolveResultWithServerTiming);
|
|
167
|
+
// eslint-disable-next-line max-depth
|
|
168
|
+
if (resolveResultWithServerTiming.error != null) {
|
|
169
|
+
throw resolveResultWithServerTiming.error;
|
|
170
|
+
}
|
|
171
|
+
resolveResult = resolveResultWithServerTiming.result;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
resolveResult = await ipns.resolveDNSLink(decodedDnsLinkLabel, options);
|
|
175
|
+
}
|
|
151
176
|
cid = resolveResult?.cid;
|
|
152
177
|
resolvedPath = resolveResult?.path;
|
|
153
178
|
log.trace('resolved %s to %c', decodedDnsLinkLabel, cid);
|
|
@@ -195,7 +220,8 @@ export async function parseUrlString({ urlString, ipns, logger }, options) {
|
|
|
195
220
|
path: joinPaths(resolvedPath, urlPath ?? ''),
|
|
196
221
|
query,
|
|
197
222
|
ttl,
|
|
198
|
-
ipfsPath: `/${protocol}/${cidOrPeerIdOrDnsLink}${urlPath != null && urlPath !== '' ? `/${urlPath}` : ''}
|
|
223
|
+
ipfsPath: `/${protocol}/${cidOrPeerIdOrDnsLink}${urlPath != null && urlPath !== '' ? `/${urlPath}` : ''}`,
|
|
224
|
+
serverTimings
|
|
199
225
|
};
|
|
200
226
|
}
|
|
201
227
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-url-string.js","sourceRoot":"","sources":["../../../src/utils/parse-url-string.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAMhC,MAAM,SAAS,GAAG,IAAI,IAAI,CAA2C,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"parse-url-string.js","sourceRoot":"","sources":["../../../src/utils/parse-url-string.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ServerTimingSuccess<T> {
|
|
2
|
+
error: null;
|
|
3
|
+
result: T;
|
|
4
|
+
header: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ServerTimingError {
|
|
7
|
+
result: null;
|
|
8
|
+
error: Error;
|
|
9
|
+
header: string;
|
|
10
|
+
}
|
|
11
|
+
export type ServerTimingResult<T> = ServerTimingSuccess<T> | ServerTimingError;
|
|
12
|
+
export declare function serverTiming<T>(name: string, description: string, fn: () => Promise<T>): Promise<ServerTimingResult<T>>;
|
|
13
|
+
//# sourceMappingURL=server-timing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-timing.d.ts","sourceRoot":"","sources":["../../../src/utils/server-timing.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,KAAK,EAAE,IAAI,CAAA;IACX,MAAM,EAAE,CAAC,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf;AACD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,IAAI,CAAA;IACZ,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AACD,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAA;AAE9E,wBAAsB,YAAY,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAoBhC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export async function serverTiming(name, description, fn) {
|
|
2
|
+
const startTime = performance.now();
|
|
3
|
+
try {
|
|
4
|
+
const result = await fn(); // Execute the function
|
|
5
|
+
const endTime = performance.now();
|
|
6
|
+
const duration = (endTime - startTime).toFixed(1); // Duration in milliseconds
|
|
7
|
+
// Create the Server-Timing header string
|
|
8
|
+
const header = `${name};dur=${duration};desc="${description}"`;
|
|
9
|
+
return { result, header, error: null };
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
const endTime = performance.now();
|
|
13
|
+
const duration = (endTime - startTime).toFixed(1);
|
|
14
|
+
// Still return a timing header even on error
|
|
15
|
+
const header = `${name};dur=${duration};desc="${description}"`;
|
|
16
|
+
return { result: null, error, header }; // Pass error with timing info
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=server-timing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-timing.js","sourceRoot":"","sources":["../../../src/utils/server-timing.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,WAAmB,EACnB,EAAoB;IAEpB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;IAEnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAA,CAAC,uBAAuB;QACjD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAEjC,MAAM,QAAQ,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,CAAC,2BAA2B;QAE7E,yCAAyC;QACzC,MAAM,MAAM,GAAG,GAAG,IAAI,QAAQ,QAAQ,UAAU,WAAW,GAAG,CAAA;QAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QACjC,MAAM,QAAQ,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAEjD,6CAA6C;QAC7C,MAAM,MAAM,GAAG,GAAG,IAAI,QAAQ,QAAQ,UAAU,WAAW,GAAG,CAAA;QAC9D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA,CAAC,8BAA8B;IACvE,CAAC;AACH,CAAC"}
|
|
@@ -11,6 +11,8 @@ export declare class VerifiedFetch {
|
|
|
11
11
|
private readonly log;
|
|
12
12
|
private readonly contentTypeParser;
|
|
13
13
|
private readonly blockstoreSessions;
|
|
14
|
+
private serverTimingHeaders;
|
|
15
|
+
private readonly withServerTiming;
|
|
14
16
|
constructor({ helia, ipns }: VerifiedFetchComponents, init?: CreateVerifiedFetchOptions);
|
|
15
17
|
private getBlockstore;
|
|
16
18
|
/**
|
|
@@ -37,6 +39,13 @@ export declare class VerifiedFetch {
|
|
|
37
39
|
* use the CID codec to choose an appropriate handler for the block data.
|
|
38
40
|
*/
|
|
39
41
|
private readonly codecHandlers;
|
|
42
|
+
private handleServerTiming;
|
|
43
|
+
/**
|
|
44
|
+
* The last place a Response touches in verified-fetch before being returned to the user. This is where we add the
|
|
45
|
+
* Server-Timing header to the response if it has been collected. It should be used for any final processing of the
|
|
46
|
+
* response before it is returned to the user.
|
|
47
|
+
*/
|
|
48
|
+
private handleFinalResponse;
|
|
40
49
|
/**
|
|
41
50
|
* We're starting to get to the point where we need a queue or pipeline of
|
|
42
51
|
* operations to perform and a single place to handle errors.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verified-fetch.d.ts","sourceRoot":"","sources":["../../src/verified-fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,IAAI,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"verified-fetch.d.ts","sourceRoot":"","sources":["../../src/verified-fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,IAAI,EAAE,MAAM,aAAa,CAAA;AAoC1D,OAAO,KAAK,EAAgC,0BAA0B,EAAE,QAAQ,EAAkB,iBAAiB,IAAI,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAE/J,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAA;AAMhE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,KAAK,CAAA;IACZ,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ;AA4DD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA+B;IACjE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqC;IACxE,OAAO,CAAC,mBAAmB,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE7B,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,uBAAuB,EAAE,IAAI,CAAC,EAAE,0BAA0B;IAgBxF,OAAO,CAAC,aAAa;IAgBrB;;;OAGG;YACW,gBAAgB;IAyC9B;;;OAGG;YACW,SAAS;IAWvB;;;OAGG;YACW,SAAS;YAcT,UAAU;YA2BV,aAAa;YAiEb,WAAW;YAuGX,SAAS;IA2BvB;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAO7B;YAEa,kBAAkB;IAahC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;;;;;OAMG;IACG,KAAK,CAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqHhF;;OAEG;IACG,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAI7B;;OAEG;IACG,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -32,6 +32,7 @@ import { resourceToSessionCacheKey } from './utils/resource-to-cache-key.js';
|
|
|
32
32
|
import { setCacheControlHeader, setIpfsRoots } from './utils/response-headers.js';
|
|
33
33
|
import { badRequestResponse, movedPermanentlyResponse, notAcceptableResponse, notSupportedResponse, okResponse, badRangeResponse, okRangeResponse, badGatewayResponse, notFoundResponse } from './utils/responses.js';
|
|
34
34
|
import { selectOutputType } from './utils/select-output-type.js';
|
|
35
|
+
import { serverTiming } from './utils/server-timing.js';
|
|
35
36
|
import { setContentType } from './utils/set-content-type.js';
|
|
36
37
|
import { handlePathWalking, isObjectNode } from './utils/walk-path.js';
|
|
37
38
|
const SESSION_CACHE_MAX_SIZE = 100;
|
|
@@ -89,6 +90,8 @@ export class VerifiedFetch {
|
|
|
89
90
|
log;
|
|
90
91
|
contentTypeParser;
|
|
91
92
|
blockstoreSessions;
|
|
93
|
+
serverTimingHeaders = [];
|
|
94
|
+
withServerTiming;
|
|
92
95
|
constructor({ helia, ipns }, init) {
|
|
93
96
|
this.helia = helia;
|
|
94
97
|
this.log = helia.logger.forComponent('helia:verified-fetch');
|
|
@@ -101,6 +104,7 @@ export class VerifiedFetch {
|
|
|
101
104
|
store.close();
|
|
102
105
|
}
|
|
103
106
|
});
|
|
107
|
+
this.withServerTiming = init?.withServerTiming ?? false;
|
|
104
108
|
this.log.trace('created VerifiedFetch instance');
|
|
105
109
|
}
|
|
106
110
|
getBlockstore(root, resource, useSession, options) {
|
|
@@ -207,12 +211,12 @@ export class VerifiedFetch {
|
|
|
207
211
|
response.headers.set('content-type', accept ?? 'application/json');
|
|
208
212
|
return response;
|
|
209
213
|
}
|
|
210
|
-
async handleDagCbor({ resource, cid, path, accept, session, options }) {
|
|
214
|
+
async handleDagCbor({ resource, cid, path, accept, session, options, withServerTiming }) {
|
|
211
215
|
this.log.trace('fetching %c/%s', cid, path);
|
|
212
216
|
let terminalElement;
|
|
213
217
|
const blockstore = this.getBlockstore(cid, resource, session, options);
|
|
214
218
|
// need to walk path, if it exists, to get the terminal element
|
|
215
|
-
const pathDetails = await handlePathWalking({ cid, path, resource, options, blockstore, log: this.log });
|
|
219
|
+
const pathDetails = await this.handleServerTiming('path-walking', '', async () => handlePathWalking({ cid, path, resource, options, blockstore, log: this.log, withServerTiming }), withServerTiming);
|
|
216
220
|
if (pathDetails instanceof Response) {
|
|
217
221
|
return pathDetails;
|
|
218
222
|
}
|
|
@@ -265,11 +269,11 @@ export class VerifiedFetch {
|
|
|
265
269
|
setIpfsRoots(response, ipfsRoots);
|
|
266
270
|
return response;
|
|
267
271
|
}
|
|
268
|
-
async handleDagPb({ cid, path, resource, session, options }) {
|
|
272
|
+
async handleDagPb({ cid, path, resource, session, options, withServerTiming }) {
|
|
269
273
|
let redirected = false;
|
|
270
274
|
const byteRangeContext = new ByteRangeContext(this.helia.logger, options?.headers);
|
|
271
275
|
const blockstore = this.getBlockstore(cid, resource, session, options);
|
|
272
|
-
const pathDetails = await handlePathWalking({ cid, path, resource, options, blockstore, log: this.log });
|
|
276
|
+
const pathDetails = await this.handleServerTiming('path-walking', '', async () => handlePathWalking({ cid, path, resource, options, blockstore, log: this.log, withServerTiming }), withServerTiming);
|
|
273
277
|
if (pathDetails instanceof Response) {
|
|
274
278
|
return pathDetails;
|
|
275
279
|
}
|
|
@@ -296,10 +300,10 @@ export class VerifiedFetch {
|
|
|
296
300
|
const rootFilePath = 'index.html';
|
|
297
301
|
try {
|
|
298
302
|
this.log.trace('found directory at %c/%s, looking for index.html', cid, path);
|
|
299
|
-
const entry = await exporter(`/ipfs/${dirCid}/${rootFilePath}`, this.helia.blockstore, {
|
|
303
|
+
const entry = await this.handleServerTiming('exporter-dir', '', async () => exporter(`/ipfs/${dirCid}/${rootFilePath}`, this.helia.blockstore, {
|
|
300
304
|
signal: options?.signal,
|
|
301
305
|
onProgress: options?.onProgress
|
|
302
|
-
});
|
|
306
|
+
}), withServerTiming);
|
|
303
307
|
this.log.trace('found root file at %c/%s with cid %c', dirCid, rootFilePath, entry.cid);
|
|
304
308
|
path = rootFilePath;
|
|
305
309
|
resolvedCID = entry.cid;
|
|
@@ -322,10 +326,10 @@ export class VerifiedFetch {
|
|
|
322
326
|
const length = byteRangeContext.length;
|
|
323
327
|
this.log.trace('calling exporter for %c/%s with offset=%o & length=%o', resolvedCID, path, offset, length);
|
|
324
328
|
try {
|
|
325
|
-
const entry = await exporter(resolvedCID, this.helia.blockstore, {
|
|
329
|
+
const entry = await this.handleServerTiming('exporter-file', '', async () => exporter(resolvedCID, this.helia.blockstore, {
|
|
326
330
|
signal: options?.signal,
|
|
327
331
|
onProgress: options?.onProgress
|
|
328
|
-
});
|
|
332
|
+
}), withServerTiming);
|
|
329
333
|
const asyncIter = entry.content({
|
|
330
334
|
signal: options?.signal,
|
|
331
335
|
onProgress: options?.onProgress,
|
|
@@ -333,16 +337,16 @@ export class VerifiedFetch {
|
|
|
333
337
|
length
|
|
334
338
|
});
|
|
335
339
|
this.log('got async iterator for %c/%s', cid, path);
|
|
336
|
-
const { stream, firstChunk } = await getStreamFromAsyncIterable(asyncIter, path ?? '', this.helia.logger, {
|
|
340
|
+
const { stream, firstChunk } = await this.handleServerTiming('stream-and-chunk', '', async () => getStreamFromAsyncIterable(asyncIter, path ?? '', this.helia.logger, {
|
|
337
341
|
onProgress: options?.onProgress,
|
|
338
342
|
signal: options?.signal
|
|
339
|
-
});
|
|
343
|
+
}), withServerTiming);
|
|
340
344
|
byteRangeContext.setBody(stream);
|
|
341
345
|
// if not a valid range request, okRangeRequest will call okResponse
|
|
342
346
|
const response = okRangeResponse(resource, byteRangeContext.getBody(), { byteRangeContext, log: this.log }, {
|
|
343
347
|
redirected
|
|
344
348
|
});
|
|
345
|
-
await setContentType({ bytes: firstChunk, path, response, contentTypeParser: this.contentTypeParser, log: this.log });
|
|
349
|
+
await this.handleServerTiming('set-content-type', '', async () => setContentType({ bytes: firstChunk, path, response, contentTypeParser: this.contentTypeParser, log: this.log }), withServerTiming);
|
|
346
350
|
setIpfsRoots(response, ipfsRoots);
|
|
347
351
|
return response;
|
|
348
352
|
}
|
|
@@ -390,6 +394,30 @@ export class VerifiedFetch {
|
|
|
390
394
|
[rawCode]: this.handleRaw,
|
|
391
395
|
[identity.code]: this.handleRaw
|
|
392
396
|
};
|
|
397
|
+
async handleServerTiming(name, description, fn, withServerTiming) {
|
|
398
|
+
if (!withServerTiming) {
|
|
399
|
+
return fn();
|
|
400
|
+
}
|
|
401
|
+
const { error, result, header } = await serverTiming(name, description, fn);
|
|
402
|
+
this.serverTimingHeaders.push(header);
|
|
403
|
+
if (error != null) {
|
|
404
|
+
throw error;
|
|
405
|
+
}
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* The last place a Response touches in verified-fetch before being returned to the user. This is where we add the
|
|
410
|
+
* Server-Timing header to the response if it has been collected. It should be used for any final processing of the
|
|
411
|
+
* response before it is returned to the user.
|
|
412
|
+
*/
|
|
413
|
+
handleFinalResponse(response) {
|
|
414
|
+
if (this.serverTimingHeaders.length > 0) {
|
|
415
|
+
const headerString = this.serverTimingHeaders.join(', ');
|
|
416
|
+
response.headers.set('Server-Timing', headerString);
|
|
417
|
+
this.serverTimingHeaders = [];
|
|
418
|
+
}
|
|
419
|
+
return response;
|
|
420
|
+
}
|
|
393
421
|
/**
|
|
394
422
|
* We're starting to get to the point where we need a queue or pipeline of
|
|
395
423
|
* operations to perform and a single place to handle errors.
|
|
@@ -400,6 +428,7 @@ export class VerifiedFetch {
|
|
|
400
428
|
async fetch(resource, opts) {
|
|
401
429
|
this.log('fetch %s', resource);
|
|
402
430
|
const options = convertOptions(opts);
|
|
431
|
+
const withServerTiming = options?.withServerTiming ?? this.withServerTiming;
|
|
403
432
|
options?.onProgress?.(new CustomProgressEvent('verified-fetch:request:start', { resource }));
|
|
404
433
|
// resolve the CID/path from the requested resource
|
|
405
434
|
let cid;
|
|
@@ -409,33 +438,34 @@ export class VerifiedFetch {
|
|
|
409
438
|
let protocol;
|
|
410
439
|
let ipfsPath;
|
|
411
440
|
try {
|
|
412
|
-
const result = await parseResource(resource, { ipns: this.ipns, logger: this.helia.logger }, options);
|
|
441
|
+
const result = await this.handleServerTiming('parse-resource', '', async () => parseResource(resource, { ipns: this.ipns, logger: this.helia.logger }, { withServerTiming, ...options }), withServerTiming);
|
|
413
442
|
cid = result.cid;
|
|
414
443
|
path = result.path;
|
|
415
444
|
query = result.query;
|
|
416
445
|
ttl = result.ttl;
|
|
417
446
|
protocol = result.protocol;
|
|
418
447
|
ipfsPath = result.ipfsPath;
|
|
448
|
+
this.serverTimingHeaders.push(...result.serverTimings.map(({ header }) => header));
|
|
419
449
|
}
|
|
420
450
|
catch (err) {
|
|
421
451
|
options?.signal?.throwIfAborted();
|
|
422
452
|
this.log.error('error parsing resource %s', resource, err);
|
|
423
|
-
return badRequestResponse(resource.toString(), err);
|
|
453
|
+
return this.handleFinalResponse(badRequestResponse(resource.toString(), err));
|
|
424
454
|
}
|
|
425
455
|
options?.onProgress?.(new CustomProgressEvent('verified-fetch:request:resolve', { cid, path }));
|
|
426
456
|
const acceptHeader = getResolvedAcceptHeader({ query, headers: options?.headers, logger: this.helia.logger });
|
|
427
457
|
const accept = selectOutputType(cid, acceptHeader);
|
|
428
458
|
this.log('output type %s', accept);
|
|
429
459
|
if (acceptHeader != null && accept == null) {
|
|
430
|
-
return notAcceptableResponse(resource.toString());
|
|
460
|
+
return this.handleFinalResponse(notAcceptableResponse(resource.toString()));
|
|
431
461
|
}
|
|
432
462
|
let response;
|
|
433
463
|
let reqFormat;
|
|
434
464
|
const redirectResponse = await getRedirectResponse({ resource, options, logger: this.helia.logger, cid });
|
|
435
465
|
if (redirectResponse != null) {
|
|
436
|
-
return redirectResponse;
|
|
466
|
+
return this.handleFinalResponse(redirectResponse);
|
|
437
467
|
}
|
|
438
|
-
const handlerArgs = { resource: resource.toString(), cid, path, accept, session: options?.session ?? true, options };
|
|
468
|
+
const handlerArgs = { resource: resource.toString(), cid, path, accept, session: options?.session ?? true, options, withServerTiming };
|
|
439
469
|
if (accept === 'application/vnd.ipfs.ipns-record') {
|
|
440
470
|
// the user requested a raw IPNS record
|
|
441
471
|
reqFormat = 'ipns-record';
|
|
@@ -467,7 +497,7 @@ export class VerifiedFetch {
|
|
|
467
497
|
// derive the handler from the CID type
|
|
468
498
|
const codecHandler = this.codecHandlers[cid.code];
|
|
469
499
|
if (codecHandler == null) {
|
|
470
|
-
return notSupportedResponse(`Support for codec with code ${cid.code} is not yet implemented. Please open an issue at https://github.com/ipfs/helia-verified-fetch/issues/new`);
|
|
500
|
+
return this.handleFinalResponse(notSupportedResponse(`Support for codec with code ${cid.code} is not yet implemented. Please open an issue at https://github.com/ipfs/helia-verified-fetch/issues/new`));
|
|
471
501
|
}
|
|
472
502
|
this.log.trace('calling handler "%s"', codecHandler.name);
|
|
473
503
|
response = await codecHandler.call(this, handlerArgs);
|
|
@@ -492,7 +522,7 @@ export class VerifiedFetch {
|
|
|
492
522
|
response.headers.set('Content-Disposition', contentDisposition);
|
|
493
523
|
}
|
|
494
524
|
options?.onProgress?.(new CustomProgressEvent('verified-fetch:request:end', { cid, path }));
|
|
495
|
-
return response;
|
|
525
|
+
return this.handleFinalResponse(response);
|
|
496
526
|
}
|
|
497
527
|
/**
|
|
498
528
|
* Start the Helia instance
|