@helia/block-brokers 4.2.2 → 4.2.3
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 +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +4 -4
- package/dist/src/trustless-gateway/broker.js +1 -1
- package/dist/src/trustless-gateway/broker.js.map +1 -1
- package/dist/src/trustless-gateway/index.d.ts +6 -0
- package/dist/src/trustless-gateway/index.d.ts.map +1 -1
- package/dist/src/trustless-gateway/index.js +6 -0
- package/dist/src/trustless-gateway/index.js.map +1 -1
- package/dist/src/trustless-gateway/session.js +1 -1
- package/dist/src/trustless-gateway/session.js.map +1 -1
- package/dist/src/trustless-gateway/trustless-gateway.d.ts +10 -1
- package/dist/src/trustless-gateway/trustless-gateway.d.ts.map +1 -1
- package/dist/src/trustless-gateway/trustless-gateway.js +7 -2
- package/dist/src/trustless-gateway/trustless-gateway.js.map +1 -1
- package/dist/src/trustless-gateway/utils.d.ts +13 -1
- package/dist/src/trustless-gateway/utils.d.ts.map +1 -1
- package/dist/src/trustless-gateway/utils.js +55 -0
- package/dist/src/trustless-gateway/utils.js.map +1 -1
- package/package.json +7 -6
- package/src/trustless-gateway/broker.ts +1 -1
- package/src/trustless-gateway/index.ts +6 -0
- package/src/trustless-gateway/session.ts +1 -1
- package/src/trustless-gateway/trustless-gateway.ts +18 -2
- package/src/trustless-gateway/utils.ts +68 -1
|
@@ -25,7 +25,7 @@ export class TrustlessGatewayBlockBroker {
|
|
|
25
25
|
for await (const gateway of findHttpGatewayProviders(cid, this.routing, this.logger, this.allowInsecure, this.allowLocal, { ...options, transformRequestInit: this.transformRequestInit })) {
|
|
26
26
|
this.log('getting block for %c from %s', cid, gateway.url);
|
|
27
27
|
try {
|
|
28
|
-
const block = await gateway.getRawBlock(cid, options
|
|
28
|
+
const block = await gateway.getRawBlock(cid, options);
|
|
29
29
|
this.log.trace('got block for %c from %s', cid, gateway.url);
|
|
30
30
|
try {
|
|
31
31
|
await options.validateFn?.(block);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../../src/trustless-gateway/broker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AA6BxE;;;GAGG;AACH,MAAM,OAAO,2BAA2B;IACrB,aAAa,CAAS;IACtB,UAAU,CAAS;IACnB,oBAAoB,CAAuB;IAC3C,OAAO,CAAS;IAChB,GAAG,CAAQ;IACX,MAAM,CAAiB;IAExC,YAAa,UAAiD,EAAE,OAAwC,EAAE;QACxG,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,sCAAsC,CAAC,CAAA;QACjF,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;QAC/B,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;QACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,sBAAsB,CAAA;QACjE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,mBAAmB,CAAA;QACxD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAE,GAAQ,EAAE,UAAyE,EAAE;QACnG,MAAM,eAAe,GAAY,EAAE,CAAA;QAEnC,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,wBAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,OAAO,EAAE,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,EAAE,CAAC;YAC3L,IAAI,CAAC,GAAG,CAAC,8BAA8B,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;YAE1D,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../../src/trustless-gateway/broker.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,12 @@ import type { ComponentLogger } from '@libp2p/interface';
|
|
|
4
4
|
import type { ProgressEvent } from 'progress-events';
|
|
5
5
|
export declare const DEFAULT_ALLOW_INSECURE = false;
|
|
6
6
|
export declare const DEFAULT_ALLOW_LOCAL = false;
|
|
7
|
+
/**
|
|
8
|
+
* The maximum number of bytes to allow when fetching a raw block.
|
|
9
|
+
*
|
|
10
|
+
* @see https://specs.ipfs.tech/bitswap-protocol/#block-sizes
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_MAX_SIZE = 2097152;
|
|
7
13
|
export type TrustlessGatewayGetBlockProgressEvents = ProgressEvent<'trustless-gateway:get-block:fetch', URL>;
|
|
8
14
|
export interface TrustlessGatewayBlockBrokerInit {
|
|
9
15
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/trustless-gateway/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,eAAO,MAAM,sBAAsB,QAAQ,CAAA;AAC3C,eAAO,MAAM,mBAAmB,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/trustless-gateway/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,eAAO,MAAM,sBAAsB,QAAQ,CAAA;AAC3C,eAAO,MAAM,mBAAmB,QAAQ,CAAA;AACxC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,UAAY,CAAA;AAEzC,MAAM,MAAM,sCAAsC,GAChD,aAAa,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAA;AAEzD,MAAM,WAAW,+BAA+B;IAC9C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;OAEG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;CAC5C;AAED,MAAM,WAAW,qCAAqC;IACpD,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,wBAAgB,gBAAgB,CAAE,IAAI,GAAE,+BAAoC,GAAG,CAAC,UAAU,EAAE,qCAAqC,KAAK,WAAW,CAAC,sCAAsC,CAAC,CAExL"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { TrustlessGatewayBlockBroker } from './broker.js';
|
|
2
2
|
export const DEFAULT_ALLOW_INSECURE = false;
|
|
3
3
|
export const DEFAULT_ALLOW_LOCAL = false;
|
|
4
|
+
/**
|
|
5
|
+
* The maximum number of bytes to allow when fetching a raw block.
|
|
6
|
+
*
|
|
7
|
+
* @see https://specs.ipfs.tech/bitswap-protocol/#block-sizes
|
|
8
|
+
*/
|
|
9
|
+
export const DEFAULT_MAX_SIZE = 2_097_152;
|
|
4
10
|
export function trustlessGateway(init = {}) {
|
|
5
11
|
return (components) => new TrustlessGatewayBlockBroker(components, init);
|
|
6
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/trustless-gateway/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAMzD,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAA;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/trustless-gateway/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAMzD,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAA;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAA;AACxC;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAAA;AAgCzC,MAAM,UAAU,gBAAgB,CAAE,OAAwC,EAAE;IAC1E,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,2BAA2B,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AAC1E,CAAC"}
|
|
@@ -21,7 +21,7 @@ class TrustlessGatewaySession extends AbstractSession {
|
|
|
21
21
|
}
|
|
22
22
|
async queryProvider(cid, provider, options) {
|
|
23
23
|
this.log('fetching BLOCK for %c from %s', cid, provider.url);
|
|
24
|
-
const block = await provider.getRawBlock(cid, options
|
|
24
|
+
const block = await provider.getRawBlock(cid, options);
|
|
25
25
|
this.log.trace('got block for %c from %s', cid, provider.url);
|
|
26
26
|
await options.validateFn?.(block);
|
|
27
27
|
return block;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/trustless-gateway/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAexE,MAAM,uBAAwB,SAAQ,eAAyE;IAC5F,OAAO,CAAS;IAChB,aAAa,CAAS;IACtB,UAAU,CAAS;IACnB,oBAAoB,CAAuB;IAE5D,YAAa,UAA6C,EAAE,IAA0C;QACpG,KAAK,CAAC,UAAU,EAAE;YAChB,GAAG,IAAI;YACP,IAAI,EAAE,iCAAiC;SACxC,CAAC,CAAA;QAEF,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;QACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,sBAAsB,CAAA;QACjE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,mBAAmB,CAAA;QACxD,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,aAAa,CAAE,GAAQ,EAAE,QAA0B,EAAE,OAA8B;QACvF,IAAI,CAAC,GAAG,CAAC,+BAA+B,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAA;QAE5D,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/trustless-gateway/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,15 @@ export interface TrustlessGatewayComponents {
|
|
|
14
14
|
logger: ComponentLogger;
|
|
15
15
|
transformRequestInit?: TransformRequestInit;
|
|
16
16
|
}
|
|
17
|
+
export interface GetRawBlockOptions {
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
/**
|
|
20
|
+
* The maximum number of bytes to allow when fetching a raw block.
|
|
21
|
+
*
|
|
22
|
+
* @default 2_097_152 (2MiB)
|
|
23
|
+
*/
|
|
24
|
+
maxSize?: number;
|
|
25
|
+
}
|
|
17
26
|
/**
|
|
18
27
|
* A `TrustlessGateway` keeps track of the number of attempts, errors, and
|
|
19
28
|
* successes for a given gateway url so that we can prioritize gateways that
|
|
@@ -30,7 +39,7 @@ export declare class TrustlessGateway {
|
|
|
30
39
|
* Fetch a raw block from `this.url` following the specification defined at
|
|
31
40
|
* https://specs.ipfs.tech/http-gateways/trustless-gateway/
|
|
32
41
|
*/
|
|
33
|
-
getRawBlock(cid: CID, signal?:
|
|
42
|
+
getRawBlock(cid: CID, { signal, maxSize }?: GetRawBlockOptions): Promise<Uint8Array>;
|
|
34
43
|
/**
|
|
35
44
|
* Encapsulate the logic for determining whether a gateway is considered
|
|
36
45
|
* reliable, for prioritization. This is based on the number of successful attempts made
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trustless-gateway.d.ts","sourceRoot":"","sources":["../../../src/trustless-gateway/trustless-gateway.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"trustless-gateway.d.ts","sourceRoot":"","sources":["../../../src/trustless-gateway/trustless-gateway.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,mBAAmB,CAAA;AAChE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAAA;CAClE;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,eAAe,CAAA;IACvB,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAA;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;;IAC3B,SAAgB,GAAG,EAAE,GAAG,CAAA;IAoCxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAsB;gBAE/C,GAAG,EAAE,GAAG,GAAG,MAAM,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,0BAA0B;IAoB5F;;;OAGG;IACG,WAAW,CAAE,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,OAA0B,EAAE,GAAE,kBAAuB,GAAG,OAAO,CAAC,UAAU,CAAC;IAgElH;;;;;;;OAOG;IACH,WAAW,IAAK,MAAM;IAyBtB;;OAEG;IACH,sBAAsB,IAAK,IAAI;IAI/B,QAAQ,IAAK,qBAAqB;CASnC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { base64 } from 'multiformats/bases/base64';
|
|
2
|
+
import { limitedResponse } from './utils.js';
|
|
3
|
+
import { DEFAULT_MAX_SIZE } from './index.js';
|
|
2
4
|
/**
|
|
3
5
|
* A `TrustlessGateway` keeps track of the number of attempts, errors, and
|
|
4
6
|
* successes for a given gateway url so that we can prioritize gateways that
|
|
@@ -61,7 +63,7 @@ export class TrustlessGateway {
|
|
|
61
63
|
* Fetch a raw block from `this.url` following the specification defined at
|
|
62
64
|
* https://specs.ipfs.tech/http-gateways/trustless-gateway/
|
|
63
65
|
*/
|
|
64
|
-
async getRawBlock(cid, signal) {
|
|
66
|
+
async getRawBlock(cid, { signal, maxSize = DEFAULT_MAX_SIZE } = {}) {
|
|
65
67
|
const gwUrl = new URL(this.url.toString());
|
|
66
68
|
gwUrl.pathname = `/ipfs/${cid.toString()}`;
|
|
67
69
|
// necessary as not every gateway supports dag-cbor, but every should support
|
|
@@ -95,8 +97,11 @@ export class TrustlessGateway {
|
|
|
95
97
|
this.#errors++;
|
|
96
98
|
throw new Error(`unable to fetch raw block for CID ${cid} from gateway ${this.url}`);
|
|
97
99
|
}
|
|
100
|
+
// limited Response ensures the body is less than 2MiB (or configurable maxSize)
|
|
101
|
+
// see https://github.com/ipfs/helia/issues/790
|
|
102
|
+
const body = await limitedResponse(res, maxSize, { signal: innerController.signal, log: this.log });
|
|
98
103
|
this.#successes++;
|
|
99
|
-
return
|
|
104
|
+
return body;
|
|
100
105
|
});
|
|
101
106
|
this.#pendingResponses.set(blockId, pendingResponse);
|
|
102
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trustless-gateway.js","sourceRoot":"","sources":["../../../src/trustless-gateway/trustless-gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"trustless-gateway.js","sourceRoot":"","sources":["../../../src/trustless-gateway/trustless-gateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TrustlessGateway } from './trustless-gateway.js';
|
|
2
2
|
import type { TransformRequestInit } from './trustless-gateway.js';
|
|
3
3
|
import type { Routing } from '@helia/interface';
|
|
4
|
-
import type { ComponentLogger } from '@libp2p/interface';
|
|
4
|
+
import type { ComponentLogger, Logger } from '@libp2p/interface';
|
|
5
5
|
import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr';
|
|
6
6
|
import type { CID } from 'multiformats/cid';
|
|
7
7
|
export declare function filterNonHTTPMultiaddrs(multiaddrs: Multiaddr[], allowInsecure: boolean, allowLocal: boolean): Multiaddr[];
|
|
@@ -9,4 +9,16 @@ export interface FindHttpGatewayProvidersOptions extends AbortOptions {
|
|
|
9
9
|
transformRequestInit?: TransformRequestInit;
|
|
10
10
|
}
|
|
11
11
|
export declare function findHttpGatewayProviders(cid: CID, routing: Routing, logger: ComponentLogger, allowInsecure: boolean, allowLocal: boolean, options?: FindHttpGatewayProvidersOptions): AsyncGenerator<TrustlessGateway>;
|
|
12
|
+
interface LimitedResponseOptions {
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
log?: Logger;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A function that handles ensuring the content-length header and the response body is less than a given byte limit.
|
|
18
|
+
*
|
|
19
|
+
* If the response contains a content-length header greater than the limit or the actual bytes returned are greater than
|
|
20
|
+
* the limit, an error is thrown.
|
|
21
|
+
*/
|
|
22
|
+
export declare function limitedResponse(response: Response, byteLimit: number, options?: LimitedResponseOptions): Promise<Uint8Array>;
|
|
23
|
+
export {};
|
|
12
24
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/trustless-gateway/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/trustless-gateway/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,wBAAgB,uBAAuB,CAAE,UAAU,EAAE,SAAS,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,GAAG,SAAS,EAAE,CAwB1H;AAED,MAAM,WAAW,+BAAgC,SAAQ,YAAY;IACnE,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;CAC5C;AAED,wBAAwB,wBAAwB,CAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAE,+BAAoC,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAiBnO;AAED,UAAU,sBAAsB;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAqDnI"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isPrivateIp } from '@libp2p/utils/private-ip';
|
|
2
2
|
import { DNS, HTTP, HTTPS } from '@multiformats/multiaddr-matcher';
|
|
3
3
|
import { multiaddrToUri } from '@multiformats/multiaddr-to-uri';
|
|
4
|
+
import { Uint8ArrayList } from 'uint8arraylist';
|
|
4
5
|
import { TrustlessGateway } from './trustless-gateway.js';
|
|
5
6
|
export function filterNonHTTPMultiaddrs(multiaddrs, allowInsecure, allowLocal) {
|
|
6
7
|
return multiaddrs.filter(ma => {
|
|
@@ -38,4 +39,58 @@ export async function* findHttpGatewayProviders(cid, routing, logger, allowInsec
|
|
|
38
39
|
yield new TrustlessGateway(uri, { logger, transformRequestInit: options.transformRequestInit });
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* A function that handles ensuring the content-length header and the response body is less than a given byte limit.
|
|
44
|
+
*
|
|
45
|
+
* If the response contains a content-length header greater than the limit or the actual bytes returned are greater than
|
|
46
|
+
* the limit, an error is thrown.
|
|
47
|
+
*/
|
|
48
|
+
export async function limitedResponse(response, byteLimit, options) {
|
|
49
|
+
const { signal, log } = options ?? {};
|
|
50
|
+
const contentLength = response.headers.get('content-length');
|
|
51
|
+
if (contentLength != null) {
|
|
52
|
+
const contentLengthNumber = parseInt(contentLength, 10);
|
|
53
|
+
if (contentLengthNumber > byteLimit) {
|
|
54
|
+
log?.error('content-length header (%d) is greater than the limit (%d)', contentLengthNumber, byteLimit);
|
|
55
|
+
if (response.body != null) {
|
|
56
|
+
await response.body.cancel().catch(err => {
|
|
57
|
+
log?.error('error cancelling response body after content-length check - %e', err);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
throw new Error(`Content-Length header (${contentLengthNumber}) is greater than the limit (${byteLimit}).`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const reader = response.body?.getReader();
|
|
64
|
+
if (reader == null) {
|
|
65
|
+
// no body to consume if reader is null
|
|
66
|
+
throw new Error('Response body is not readable');
|
|
67
|
+
}
|
|
68
|
+
const chunkList = new Uint8ArrayList();
|
|
69
|
+
try {
|
|
70
|
+
while (true) {
|
|
71
|
+
if (signal?.aborted === true) {
|
|
72
|
+
throw new Error('Response body read was aborted.');
|
|
73
|
+
}
|
|
74
|
+
const { done, value } = await reader.read();
|
|
75
|
+
if (done) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
chunkList.append(value);
|
|
79
|
+
if (chunkList.byteLength > byteLimit) {
|
|
80
|
+
// No need to consume body here, as we were streaming and hit the limit
|
|
81
|
+
throw new Error(`Response body is greater than the limit (${byteLimit}), received ${chunkList.byteLength} bytes.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
reader.cancel()
|
|
87
|
+
.catch(err => {
|
|
88
|
+
log?.error('error cancelling reader - %e', err);
|
|
89
|
+
})
|
|
90
|
+
.finally(() => {
|
|
91
|
+
reader.releaseLock();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return chunkList.subarray();
|
|
95
|
+
}
|
|
41
96
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/trustless-gateway/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAOzD,MAAM,UAAU,uBAAuB,CAAE,UAAuB,EAAE,aAAsB,EAAE,UAAmB;IAC3G,OAAO,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;QAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC7D,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,IAAI,CAAA;YACb,CAAC;YAED,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpB,OAAO,IAAI,CAAA;YACb,CAAC;YAED,OAAO,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,CAAA;QACnD,CAAC;QAED,gJAAgJ;QAChJ,IAAI,CAAC,aAAa,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAA;YAC/B,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChF,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CAAA;AACJ,CAAC;AAMD,MAAM,CAAC,KAAK,SAAU,CAAC,CAAC,wBAAwB,CAAE,GAAQ,EAAE,OAAgB,EAAE,MAAuB,EAAE,aAAsB,EAAE,UAAmB,EAAE,UAA2C,EAAE;IAC/L,IAAI,KAAK,EAAE,MAAM,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;QACjE,4BAA4B;QAC5B,MAAM,aAAa,GAAG,uBAAuB,CAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;QAE7F,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,SAAQ;QACV,CAAC;QAED,sBAAsB;QACtB,8BAA8B;QAC9B,+BAA+B;QAC/B,MAAM;QACN,MAAM,GAAG,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;QAE5C,MAAM,IAAI,gBAAgB,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAA;IACjG,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/trustless-gateway/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/block-brokers",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.3",
|
|
4
4
|
"description": "Block brokers for Helia",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/ipfs/helia/tree/main/packages/block-brokers#readme",
|
|
@@ -54,18 +54,19 @@
|
|
|
54
54
|
"test:electron-main": "aegir test -t electron-main"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@helia/bitswap": "^2.1.
|
|
58
|
-
"@helia/interface": "^5.
|
|
59
|
-
"@helia/utils": "^1.
|
|
57
|
+
"@helia/bitswap": "^2.1.3",
|
|
58
|
+
"@helia/interface": "^5.4.0",
|
|
59
|
+
"@helia/utils": "^1.4.0",
|
|
60
60
|
"@libp2p/interface": "^2.2.1",
|
|
61
61
|
"@libp2p/utils": "^6.2.1",
|
|
62
62
|
"@multiformats/multiaddr": "^12.3.3",
|
|
63
|
-
"@multiformats/multiaddr-matcher": "^
|
|
63
|
+
"@multiformats/multiaddr-matcher": "^2.0.1",
|
|
64
64
|
"@multiformats/multiaddr-to-uri": "^11.0.0",
|
|
65
65
|
"interface-blockstore": "^5.3.1",
|
|
66
66
|
"interface-store": "^6.0.2",
|
|
67
67
|
"multiformats": "^13.3.1",
|
|
68
|
-
"progress-events": "^1.0.1"
|
|
68
|
+
"progress-events": "^1.0.1",
|
|
69
|
+
"uint8arraylist": "^2.4.8"
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|
|
71
72
|
"@libp2p/crypto": "^5.0.7",
|
|
@@ -57,7 +57,7 @@ export class TrustlessGatewayBlockBroker implements BlockBroker<TrustlessGateway
|
|
|
57
57
|
this.log('getting block for %c from %s', cid, gateway.url)
|
|
58
58
|
|
|
59
59
|
try {
|
|
60
|
-
const block = await gateway.getRawBlock(cid, options
|
|
60
|
+
const block = await gateway.getRawBlock(cid, options)
|
|
61
61
|
this.log.trace('got block for %c from %s', cid, gateway.url)
|
|
62
62
|
|
|
63
63
|
try {
|
|
@@ -6,6 +6,12 @@ import type { ProgressEvent } from 'progress-events'
|
|
|
6
6
|
|
|
7
7
|
export const DEFAULT_ALLOW_INSECURE = false
|
|
8
8
|
export const DEFAULT_ALLOW_LOCAL = false
|
|
9
|
+
/**
|
|
10
|
+
* The maximum number of bytes to allow when fetching a raw block.
|
|
11
|
+
*
|
|
12
|
+
* @see https://specs.ipfs.tech/bitswap-protocol/#block-sizes
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_MAX_SIZE = 2_097_152
|
|
9
15
|
|
|
10
16
|
export type TrustlessGatewayGetBlockProgressEvents =
|
|
11
17
|
ProgressEvent<'trustless-gateway:get-block:fetch', URL>
|
|
@@ -39,7 +39,7 @@ class TrustlessGatewaySession extends AbstractSession<TrustlessGateway, Trustles
|
|
|
39
39
|
async queryProvider (cid: CID, provider: TrustlessGateway, options: BlockRetrievalOptions): Promise<Uint8Array> {
|
|
40
40
|
this.log('fetching BLOCK for %c from %s', cid, provider.url)
|
|
41
41
|
|
|
42
|
-
const block = await provider.getRawBlock(cid, options
|
|
42
|
+
const block = await provider.getRawBlock(cid, options)
|
|
43
43
|
this.log.trace('got block for %c from %s', cid, provider.url)
|
|
44
44
|
|
|
45
45
|
await options.validateFn?.(block)
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { base64 } from 'multiformats/bases/base64'
|
|
2
|
+
import { limitedResponse } from './utils.js'
|
|
3
|
+
import { DEFAULT_MAX_SIZE } from './index.js'
|
|
2
4
|
import type { ComponentLogger, Logger } from '@libp2p/interface'
|
|
3
5
|
import type { CID } from 'multiformats/cid'
|
|
4
6
|
|
|
@@ -19,6 +21,17 @@ export interface TrustlessGatewayComponents {
|
|
|
19
21
|
transformRequestInit?: TransformRequestInit
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
export interface GetRawBlockOptions {
|
|
25
|
+
signal?: AbortSignal
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The maximum number of bytes to allow when fetching a raw block.
|
|
29
|
+
*
|
|
30
|
+
* @default 2_097_152 (2MiB)
|
|
31
|
+
*/
|
|
32
|
+
maxSize?: number
|
|
33
|
+
}
|
|
34
|
+
|
|
22
35
|
/**
|
|
23
36
|
* A `TrustlessGateway` keeps track of the number of attempts, errors, and
|
|
24
37
|
* successes for a given gateway url so that we can prioritize gateways that
|
|
@@ -89,7 +102,7 @@ export class TrustlessGateway {
|
|
|
89
102
|
* Fetch a raw block from `this.url` following the specification defined at
|
|
90
103
|
* https://specs.ipfs.tech/http-gateways/trustless-gateway/
|
|
91
104
|
*/
|
|
92
|
-
async getRawBlock (cid: CID, signal
|
|
105
|
+
async getRawBlock (cid: CID, { signal, maxSize = DEFAULT_MAX_SIZE }: GetRawBlockOptions = {}): Promise<Uint8Array> {
|
|
93
106
|
const gwUrl = new URL(this.url.toString())
|
|
94
107
|
gwUrl.pathname = `/ipfs/${cid.toString()}`
|
|
95
108
|
|
|
@@ -130,8 +143,11 @@ export class TrustlessGateway {
|
|
|
130
143
|
this.#errors++
|
|
131
144
|
throw new Error(`unable to fetch raw block for CID ${cid} from gateway ${this.url}`)
|
|
132
145
|
}
|
|
146
|
+
// limited Response ensures the body is less than 2MiB (or configurable maxSize)
|
|
147
|
+
// see https://github.com/ipfs/helia/issues/790
|
|
148
|
+
const body = await limitedResponse(res, maxSize, { signal: innerController.signal, log: this.log })
|
|
133
149
|
this.#successes++
|
|
134
|
-
return
|
|
150
|
+
return body
|
|
135
151
|
})
|
|
136
152
|
this.#pendingResponses.set(blockId, pendingResponse)
|
|
137
153
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { isPrivateIp } from '@libp2p/utils/private-ip'
|
|
2
2
|
import { DNS, HTTP, HTTPS } from '@multiformats/multiaddr-matcher'
|
|
3
3
|
import { multiaddrToUri } from '@multiformats/multiaddr-to-uri'
|
|
4
|
+
import { Uint8ArrayList } from 'uint8arraylist'
|
|
4
5
|
import { TrustlessGateway } from './trustless-gateway.js'
|
|
5
6
|
import type { TransformRequestInit } from './trustless-gateway.js'
|
|
6
7
|
import type { Routing } from '@helia/interface'
|
|
7
|
-
import type { ComponentLogger } from '@libp2p/interface'
|
|
8
|
+
import type { ComponentLogger, Logger } from '@libp2p/interface'
|
|
8
9
|
import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr'
|
|
9
10
|
import type { CID } from 'multiformats/cid'
|
|
10
11
|
|
|
@@ -56,3 +57,69 @@ export async function * findHttpGatewayProviders (cid: CID, routing: Routing, lo
|
|
|
56
57
|
yield new TrustlessGateway(uri, { logger, transformRequestInit: options.transformRequestInit })
|
|
57
58
|
}
|
|
58
59
|
}
|
|
60
|
+
|
|
61
|
+
interface LimitedResponseOptions {
|
|
62
|
+
signal?: AbortSignal
|
|
63
|
+
log?: Logger
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A function that handles ensuring the content-length header and the response body is less than a given byte limit.
|
|
68
|
+
*
|
|
69
|
+
* If the response contains a content-length header greater than the limit or the actual bytes returned are greater than
|
|
70
|
+
* the limit, an error is thrown.
|
|
71
|
+
*/
|
|
72
|
+
export async function limitedResponse (response: Response, byteLimit: number, options?: LimitedResponseOptions): Promise<Uint8Array> {
|
|
73
|
+
const { signal, log } = options ?? {}
|
|
74
|
+
const contentLength = response.headers.get('content-length')
|
|
75
|
+
if (contentLength != null) {
|
|
76
|
+
const contentLengthNumber = parseInt(contentLength, 10)
|
|
77
|
+
if (contentLengthNumber > byteLimit) {
|
|
78
|
+
log?.error('content-length header (%d) is greater than the limit (%d)', contentLengthNumber, byteLimit)
|
|
79
|
+
if (response.body != null) {
|
|
80
|
+
await response.body.cancel().catch(err => {
|
|
81
|
+
log?.error('error cancelling response body after content-length check - %e', err)
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
throw new Error(`Content-Length header (${contentLengthNumber}) is greater than the limit (${byteLimit}).`)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const reader = response.body?.getReader()
|
|
89
|
+
if (reader == null) {
|
|
90
|
+
// no body to consume if reader is null
|
|
91
|
+
throw new Error('Response body is not readable')
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const chunkList = new Uint8ArrayList()
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
while (true) {
|
|
98
|
+
if (signal?.aborted === true) {
|
|
99
|
+
throw new Error('Response body read was aborted.')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const { done, value } = await reader.read()
|
|
103
|
+
if (done) {
|
|
104
|
+
break
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
chunkList.append(value)
|
|
108
|
+
|
|
109
|
+
if (chunkList.byteLength > byteLimit) {
|
|
110
|
+
// No need to consume body here, as we were streaming and hit the limit
|
|
111
|
+
throw new Error(`Response body is greater than the limit (${byteLimit}), received ${chunkList.byteLength} bytes.`)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} finally {
|
|
115
|
+
reader.cancel()
|
|
116
|
+
.catch(err => {
|
|
117
|
+
log?.error('error cancelling reader - %e', err)
|
|
118
|
+
})
|
|
119
|
+
.finally(() => {
|
|
120
|
+
reader.releaseLock()
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return chunkList.subarray()
|
|
125
|
+
}
|