orbitdb-relay-pinner 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +10 -0
- package/README.md +48 -2
- package/dist/http/pinning-http.d.ts +53 -0
- package/dist/http/pinning-http.d.ts.map +1 -0
- package/dist/http/pinning-http.js +379 -0
- package/dist/http/pinning-http.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/relay.d.ts +7 -0
- package/dist/relay.d.ts.map +1 -1
- package/dist/relay.js +75 -0
- package/dist/relay.js.map +1 -1
- package/dist/services/connectivity-debug-protocols-service.d.ts +30 -0
- package/dist/services/connectivity-debug-protocols-service.d.ts.map +1 -0
- package/dist/services/connectivity-debug-protocols-service.js +227 -0
- package/dist/services/connectivity-debug-protocols-service.js.map +1 -0
- package/dist/services/metrics.d.ts +7 -1
- package/dist/services/metrics.d.ts.map +1 -1
- package/dist/services/metrics.js +86 -197
- package/dist/services/metrics.js.map +1 -1
- package/dist/services/orbitdb-replication-service.d.ts +1 -0
- package/dist/services/orbitdb-replication-service.d.ts.map +1 -1
- package/dist/services/orbitdb-replication-service.js +8 -5
- package/dist/services/orbitdb-replication-service.js.map +1 -1
- package/docs/http-api.md +13 -7
- package/docs/implementation-plan-connectivity-http-refactor.md +23 -0
- package/docs/libp2p-service.md +17 -0
- package/docs/systemd-deployment.md +20 -4
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -63,6 +63,16 @@
|
|
|
63
63
|
# TEST_PRIVATE_KEY=
|
|
64
64
|
# RELAY_PRIV_KEY=
|
|
65
65
|
|
|
66
|
+
# --- Optional libp2p connectivity debug protocols ---
|
|
67
|
+
# Expose /connectivity-echo/1.0.0 for line-based echo tests.
|
|
68
|
+
# RELAY_CONNECTIVITY_ECHO_ENABLED=false
|
|
69
|
+
# Expose /connectivity-bulk/1.0.0 for framed bulk round-trip tests.
|
|
70
|
+
# RELAY_CONNECTIVITY_BULK_ENABLED=false
|
|
71
|
+
# Optional bulk protocol tuning (defaults: 262144 bytes, 10000ms read, 30000ms idle).
|
|
72
|
+
# RELAY_CONNECTIVITY_BULK_MAX_FRAME_BYTES=262144
|
|
73
|
+
# RELAY_CONNECTIVITY_BULK_READ_TIMEOUT_MS=10000
|
|
74
|
+
# RELAY_CONNECTIVITY_BULK_IDLE_TIMEOUT_MS=30000
|
|
75
|
+
|
|
66
76
|
# --- TLS (optional) ---
|
|
67
77
|
# disableAutoTLS=
|
|
68
78
|
# STAGING=false
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ See `AGENTS.md` for an architecture and feature guide (entrypoints, data flow, e
|
|
|
20
20
|
Install:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm i orbitdb-relay-pinner
|
|
23
|
+
npm i -g orbitdb-relay-pinner
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Run:
|
|
@@ -29,6 +29,46 @@ Run:
|
|
|
29
29
|
orbitdb-relay-pinner
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
Optional connectivity debug protocols for test tooling are disabled by default in the CLI/runtime. Enable them with env vars before startup:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
RELAY_CONNECTIVITY_ECHO_ENABLED=1 orbitdb-relay-pinner
|
|
36
|
+
RELAY_CONNECTIVITY_BULK_ENABLED=1 orbitdb-relay-pinner
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Bulk tuning is also available through `RELAY_CONNECTIVITY_BULK_MAX_FRAME_BYTES`, `RELAY_CONNECTIVITY_BULK_READ_TIMEOUT_MS`, and `RELAY_CONNECTIVITY_BULK_IDLE_TIMEOUT_MS`.
|
|
40
|
+
|
|
41
|
+
Default listener ports:
|
|
42
|
+
|
|
43
|
+
- TCP: `9091` via `RELAY_TCP_PORT`
|
|
44
|
+
- WebSocket: `9092` via `RELAY_WS_PORT`
|
|
45
|
+
- WebRTC-direct: `9093` via `RELAY_WEBRTC_PORT`
|
|
46
|
+
- QUIC: `9094` via `RELAY_QUIC_PORT`
|
|
47
|
+
- Metrics HTTP: `9090` via `METRICS_PORT`
|
|
48
|
+
- Metrics HTTPS: `9443` via `METRICS_HTTPS_PORT` when `METRICS_HTTPS_ENABLED=1`
|
|
49
|
+
|
|
50
|
+
AutoTLS notes:
|
|
51
|
+
|
|
52
|
+
- AutoTLS is enabled by default. It is only disabled if `disableAutoTLS` is set in the environment.
|
|
53
|
+
- The default startup logs do not print much AutoTLS-specific output, so it is normal not to see certificate activity unless you enable the relevant debug namespaces.
|
|
54
|
+
- When AutoTLS has provisioned a certificate for the WebSocket listener, the relay should advertise secure WebSocket multiaddrs ending in `/tls/ws`.
|
|
55
|
+
- If you use `VITE_APPEND_ANNOUNCE`, keep the public WebSocket address as plain `/ws` with your real public IP and port. Do not manually change it to `/tls/ws`; AutoTLS/domain mapping adds the secure advertised addresses at runtime.
|
|
56
|
+
- To verify WSS is live, check `GET /multiaddrs` and look for entries containing `/tls/ws`.
|
|
57
|
+
|
|
58
|
+
Show AutoTLS logs:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
DEBUG='libp2p:auto-tls,libp2p:auto-tls:*,libp2p:websockets:listener' ENABLE_GENERAL_LOGS=1 orbitdb-relay-pinner
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If you also want the relay to expose the metrics routes over HTTPS once AutoTLS has provisioned a certificate:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
METRICS_HTTPS_ENABLED=1 DEBUG='libp2p:auto-tls,libp2p:auto-tls:*,libp2p:websockets:listener' ENABLE_GENERAL_LOGS=1 orbitdb-relay-pinner
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
With those flags enabled, you should see AutoTLS messages such as certificate fetch attempts, reasons it is not fetching yet, and WebSocket HTTPS listener updates.
|
|
71
|
+
|
|
32
72
|
Test mode (deterministic peer id via `TEST_PRIVATE_KEY` or `RELAY_PRIV_KEY`):
|
|
33
73
|
|
|
34
74
|
```bash
|
|
@@ -41,7 +81,13 @@ The package still exports `startRelay()` as the compatibility wrapper used by th
|
|
|
41
81
|
|
|
42
82
|
For a fuller install + integration walkthrough, see `docs/libp2p-service.md`.
|
|
43
83
|
|
|
44
|
-
It also exports
|
|
84
|
+
It also exports reusable building blocks for embedded consumers:
|
|
85
|
+
|
|
86
|
+
- `orbitdbReplicationService()`
|
|
87
|
+
- `connectivityDebugProtocolsService()` for opt-in test/debug echo + bulk protocols
|
|
88
|
+
- `createPinningHttpRequestHandler()` and `PinningHttpServer` for `/health`, `/multiaddrs`, `/pinning/*`, and `/ipfs/*`
|
|
89
|
+
|
|
90
|
+
`orbitdbReplicationService()` mounts the OrbitDB replication + Helia pinning logic directly in any libp2p node:
|
|
45
91
|
|
|
46
92
|
```ts
|
|
47
93
|
import { createLibp2p } from 'libp2p'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import http from 'http';
|
|
2
|
+
import https from 'https';
|
|
3
|
+
import type { PinningHttpHandlers } from '../services/metrics.js';
|
|
4
|
+
export type Libp2pLike = {
|
|
5
|
+
peerId?: {
|
|
6
|
+
toString: () => string;
|
|
7
|
+
toCID?: () => {
|
|
8
|
+
bytes: Uint8Array;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
getMultiaddrs?: () => Array<{
|
|
12
|
+
toString: () => string;
|
|
13
|
+
}>;
|
|
14
|
+
getConnections?: () => unknown[];
|
|
15
|
+
};
|
|
16
|
+
type HeliaLike = any;
|
|
17
|
+
export type PinningHttpFallbackMode = 'pinned-only' | 'pinned-first-network-fallback';
|
|
18
|
+
export type PinningHttpRequestHandlerOptions = {
|
|
19
|
+
getLibp2p?: () => Libp2pLike | null;
|
|
20
|
+
pinning?: PinningHttpHandlers;
|
|
21
|
+
getHelia?: () => HeliaLike | null;
|
|
22
|
+
ipfsGateway?: {
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
fallbackMode?: PinningHttpFallbackMode;
|
|
25
|
+
catTimeoutMs?: number;
|
|
26
|
+
};
|
|
27
|
+
cors?: {
|
|
28
|
+
origin?: '*' | string[];
|
|
29
|
+
allowHeaders?: string[];
|
|
30
|
+
maxAgeSeconds?: number;
|
|
31
|
+
};
|
|
32
|
+
getMetricsHttpsInfo?: () => Record<string, unknown> | null;
|
|
33
|
+
};
|
|
34
|
+
export type JsonErrorCode = 'bad_request' | 'invalid_json' | 'missing_db_address' | 'database_not_found' | 'sync_failed' | 'invalid_cid' | 'invalid_path_encoding' | 'directory_path_required' | 'ipfs_unavailable' | 'content_not_found' | 'gateway_timeout' | 'internal_error';
|
|
35
|
+
export declare function isManagedPinningHttpPath(pathname: string): boolean;
|
|
36
|
+
export declare function createPinningHttpRequestHandler(options?: PinningHttpRequestHandlerOptions): (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
|
|
37
|
+
export type PinningHttpServerOptions = PinningHttpRequestHandlerOptions & {
|
|
38
|
+
port?: number;
|
|
39
|
+
host?: string;
|
|
40
|
+
tls?: {
|
|
41
|
+
cert: string | Buffer;
|
|
42
|
+
key: string | Buffer;
|
|
43
|
+
} | null;
|
|
44
|
+
};
|
|
45
|
+
export declare class PinningHttpServer {
|
|
46
|
+
private readonly options;
|
|
47
|
+
private server;
|
|
48
|
+
constructor(options?: PinningHttpServerOptions);
|
|
49
|
+
start(): Promise<http.Server | https.Server>;
|
|
50
|
+
stop(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=pinning-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pinning-http.d.ts","sourceRoot":"","sources":["../../src/http/pinning-http.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEjE,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM;YAAE,KAAK,EAAE,UAAU,CAAA;SAAE,CAAA;KAAE,CAAA;IACxE,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;KAAE,CAAC,CAAA;IACvD,cAAc,CAAC,EAAE,MAAM,OAAO,EAAE,CAAA;CACjC,CAAA;AAED,KAAK,SAAS,GAAG,GAAG,CAAA;AAEpB,MAAM,MAAM,uBAAuB,GAAG,aAAa,GAAG,+BAA+B,CAAA;AAErF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,SAAS,CAAC,EAAE,MAAM,UAAU,GAAG,IAAI,CAAA;IACnC,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,SAAS,GAAG,IAAI,CAAA;IACjC,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,YAAY,CAAC,EAAE,uBAAuB,CAAA;QACtC,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,GAAG,GAAG,MAAM,EAAE,CAAA;QACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;QACvB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;IACD,mBAAmB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC3D,CAAA;AAED,MAAM,MAAM,aAAa,GACrB,aAAa,GACb,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,aAAa,GACb,aAAa,GACb,uBAAuB,GACvB,yBAAyB,GACzB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,CAAA;AAiMpB,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CASlE;AAED,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,gCAAqC,IAM9E,KAAK,IAAI,CAAC,eAAe,EAAE,KAAK,IAAI,CAAC,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CA+JlF;AAED,MAAM,MAAM,wBAAwB,GAAG,gCAAgC,GAAG;IACxE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC7D,CAAA;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,MAAM,CAA0C;gBAE5C,OAAO,GAAE,wBAA6B;IAI5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAa5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ5B"}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import http from 'http';
|
|
2
|
+
import https from 'https';
|
|
3
|
+
import { unixfs } from '@helia/unixfs';
|
|
4
|
+
import { CID } from 'multiformats/cid';
|
|
5
|
+
const MAX_JSON_BODY_BYTES = 16_384;
|
|
6
|
+
const DEFAULT_CAT_TIMEOUT_MS = 120_000;
|
|
7
|
+
function pathnameOnly(urlValue) {
|
|
8
|
+
return (urlValue ?? '/').split('?')[0] || '/';
|
|
9
|
+
}
|
|
10
|
+
function firstSearchParam(reqUrl, names) {
|
|
11
|
+
const url = new URL(reqUrl || '/', 'http://pinning.local');
|
|
12
|
+
for (const name of names) {
|
|
13
|
+
const value = url.searchParams.get(name);
|
|
14
|
+
if (value != null && value.trim() !== '')
|
|
15
|
+
return value.trim();
|
|
16
|
+
}
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
function isPublicAddress(addr) {
|
|
20
|
+
if (!addr)
|
|
21
|
+
return false;
|
|
22
|
+
if (addr.includes('/ip4/127.'))
|
|
23
|
+
return false;
|
|
24
|
+
if (addr.includes('/ip4/10.'))
|
|
25
|
+
return false;
|
|
26
|
+
if (addr.includes('/ip4/192.168.'))
|
|
27
|
+
return false;
|
|
28
|
+
const m = addr.match(/\/ip4\/172\.(\d+)\./);
|
|
29
|
+
if (m) {
|
|
30
|
+
const octet = Number(m[1]);
|
|
31
|
+
if (octet >= 16 && octet <= 31)
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (addr.includes('/ip6/::1'))
|
|
35
|
+
return false;
|
|
36
|
+
if (addr.includes('/ip6/fc') || addr.includes('/ip6/fd'))
|
|
37
|
+
return false;
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
function prioritizeAddresses(addrs) {
|
|
41
|
+
return [...addrs].sort((a, b) => {
|
|
42
|
+
const aPublic = isPublicAddress(a);
|
|
43
|
+
const bPublic = isPublicAddress(b);
|
|
44
|
+
if (aPublic !== bPublic)
|
|
45
|
+
return aPublic ? -1 : 1;
|
|
46
|
+
return a.localeCompare(b);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function applyCorsHeaders(req, res, config) {
|
|
50
|
+
const originConfig = config?.origin ?? '*';
|
|
51
|
+
const requestOrigin = req.headers.origin;
|
|
52
|
+
let allowOrigin;
|
|
53
|
+
if (originConfig === '*') {
|
|
54
|
+
allowOrigin = '*';
|
|
55
|
+
}
|
|
56
|
+
else if (requestOrigin && originConfig.includes(requestOrigin)) {
|
|
57
|
+
allowOrigin = requestOrigin;
|
|
58
|
+
res.setHeader('Vary', 'Origin');
|
|
59
|
+
}
|
|
60
|
+
if (allowOrigin) {
|
|
61
|
+
res.setHeader('Access-Control-Allow-Origin', allowOrigin);
|
|
62
|
+
}
|
|
63
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, HEAD');
|
|
64
|
+
res.setHeader('Access-Control-Allow-Headers', (config?.allowHeaders && config.allowHeaders.length > 0
|
|
65
|
+
? config.allowHeaders.join(', ')
|
|
66
|
+
: 'Content-Type, Authorization'));
|
|
67
|
+
res.setHeader('Access-Control-Max-Age', String(config?.maxAgeSeconds ?? 86400));
|
|
68
|
+
}
|
|
69
|
+
function sendJson(res, status, body) {
|
|
70
|
+
res.statusCode = status;
|
|
71
|
+
res.setHeader('Content-Type', 'application/json');
|
|
72
|
+
res.end(JSON.stringify(body));
|
|
73
|
+
}
|
|
74
|
+
function sendError(res, status, code, error) {
|
|
75
|
+
sendJson(res, status, { ok: false, code, error });
|
|
76
|
+
}
|
|
77
|
+
async function readJsonBody(req) {
|
|
78
|
+
const chunks = [];
|
|
79
|
+
let total = 0;
|
|
80
|
+
for await (const chunk of req) {
|
|
81
|
+
const buf = chunk;
|
|
82
|
+
total += buf.length;
|
|
83
|
+
if (total > MAX_JSON_BODY_BYTES) {
|
|
84
|
+
throw new Error('body too large');
|
|
85
|
+
}
|
|
86
|
+
chunks.push(buf);
|
|
87
|
+
}
|
|
88
|
+
if (chunks.length === 0)
|
|
89
|
+
return {};
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
const error = new Error('Invalid JSON body');
|
|
95
|
+
error.code = 'invalid_json';
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function parseIpfsRequest(req) {
|
|
100
|
+
if (req.method !== 'GET')
|
|
101
|
+
return { handled: false };
|
|
102
|
+
const pathname = pathnameOnly(req.url);
|
|
103
|
+
if (!pathname.startsWith('/ipfs/'))
|
|
104
|
+
return { handled: false };
|
|
105
|
+
let parts;
|
|
106
|
+
try {
|
|
107
|
+
parts = pathname
|
|
108
|
+
.slice('/ipfs/'.length)
|
|
109
|
+
.split('/')
|
|
110
|
+
.filter((part) => part.length > 0)
|
|
111
|
+
.map((part) => decodeURIComponent(part));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return { handled: true, ok: false, status: 400, code: 'invalid_path_encoding', error: 'Invalid path encoding' };
|
|
115
|
+
}
|
|
116
|
+
if (parts.length === 0) {
|
|
117
|
+
return { handled: true, ok: false, status: 400, code: 'bad_request', error: 'Missing CID' };
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
handled: true,
|
|
121
|
+
ok: true,
|
|
122
|
+
cidStr: parts[0],
|
|
123
|
+
pathWithin: parts.length > 1 ? parts.slice(1).join('/') : undefined,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async function streamNetworkFallback(res, helia, parsed, timeoutMs) {
|
|
127
|
+
let cid;
|
|
128
|
+
try {
|
|
129
|
+
cid = CID.parse(parsed.cidStr);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
sendError(res, 400, 'invalid_cid', 'Invalid CID');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const controller = new AbortController();
|
|
136
|
+
const timeout = setTimeout(() => controller.abort(new Error('gateway timeout')), timeoutMs);
|
|
137
|
+
const fsApi = unixfs(helia);
|
|
138
|
+
const opts = {
|
|
139
|
+
signal: controller.signal,
|
|
140
|
+
...(parsed.pathWithin ? { path: parsed.pathWithin } : {}),
|
|
141
|
+
};
|
|
142
|
+
try {
|
|
143
|
+
const stat = await fsApi.stat(cid, opts);
|
|
144
|
+
if (stat.type === 'directory') {
|
|
145
|
+
sendError(res, 400, 'directory_path_required', 'Directory download is not supported; specify a file path under the CID');
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
res.statusCode = 200;
|
|
149
|
+
res.setHeader('Content-Type', 'application/octet-stream');
|
|
150
|
+
res.setHeader('Cache-Control', 'private, no-store');
|
|
151
|
+
for await (const chunk of fsApi.cat(cid, opts)) {
|
|
152
|
+
if (!res.write(chunk)) {
|
|
153
|
+
await new Promise((resolve, reject) => {
|
|
154
|
+
res.once('drain', resolve);
|
|
155
|
+
res.once('error', reject);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
res.end();
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
163
|
+
if (message.toLowerCase().includes('abort')) {
|
|
164
|
+
sendError(res, 504, 'gateway_timeout', 'Timed out while fetching CID over libp2p');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (message.includes('ERR_NOT_FOUND') ||
|
|
168
|
+
message.toLowerCase().includes('not found') ||
|
|
169
|
+
message.toLowerCase().includes('missing block') ||
|
|
170
|
+
message.toLowerCase().includes('no links named')) {
|
|
171
|
+
sendError(res, 404, 'content_not_found', 'Content not found on relay or network');
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (!res.headersSent) {
|
|
175
|
+
sendError(res, 502, 'internal_error', message);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
try {
|
|
179
|
+
res.destroy(error instanceof Error ? error : undefined);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// ignore
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
clearTimeout(timeout);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export function isManagedPinningHttpPath(pathname) {
|
|
191
|
+
return (pathname === '/health' ||
|
|
192
|
+
pathname === '/multiaddrs' ||
|
|
193
|
+
pathname === '/pinning/stats' ||
|
|
194
|
+
pathname === '/pinning/databases' ||
|
|
195
|
+
pathname === '/pinning/sync' ||
|
|
196
|
+
pathname.startsWith('/ipfs/'));
|
|
197
|
+
}
|
|
198
|
+
export function createPinningHttpRequestHandler(options = {}) {
|
|
199
|
+
const fallbackMode = options.ipfsGateway?.fallbackMode ?? 'pinned-first-network-fallback';
|
|
200
|
+
const catTimeoutMs = Number.isFinite(options.ipfsGateway?.catTimeoutMs)
|
|
201
|
+
? Math.max(1, Math.trunc(options.ipfsGateway?.catTimeoutMs))
|
|
202
|
+
: DEFAULT_CAT_TIMEOUT_MS;
|
|
203
|
+
return async (req, res) => {
|
|
204
|
+
applyCorsHeaders(req, res, options.cors);
|
|
205
|
+
if (req.method === 'OPTIONS') {
|
|
206
|
+
res.statusCode = 204;
|
|
207
|
+
res.end();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const pathname = pathnameOnly(req.url);
|
|
211
|
+
const pinning = options.pinning;
|
|
212
|
+
if (pathname === '/health' && req.method === 'GET') {
|
|
213
|
+
const libp2p = options.getLibp2p?.() ?? null;
|
|
214
|
+
const connections = libp2p?.getConnections?.() || [];
|
|
215
|
+
const multiaddrs = (libp2p?.getMultiaddrs?.() || []).map((ma) => ma.toString());
|
|
216
|
+
const metricsHttpsInfo = options.getMetricsHttpsInfo?.() ?? null;
|
|
217
|
+
sendJson(res, 200, {
|
|
218
|
+
status: 'ok',
|
|
219
|
+
peerId: libp2p?.peerId?.toString?.() || null,
|
|
220
|
+
connections: { active: connections.length },
|
|
221
|
+
multiaddrs: multiaddrs.length,
|
|
222
|
+
autoTlsServingZone: metricsHttpsInfo != null && 'autoTlsServingZone' in metricsHttpsInfo
|
|
223
|
+
? metricsHttpsInfo.autoTlsServingZone
|
|
224
|
+
: null,
|
|
225
|
+
metricsHttps: metricsHttpsInfo,
|
|
226
|
+
timestamp: new Date().toISOString(),
|
|
227
|
+
});
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (pathname === '/multiaddrs' && req.method === 'GET') {
|
|
231
|
+
const libp2p = options.getLibp2p?.() ?? null;
|
|
232
|
+
const all = prioritizeAddresses((libp2p?.getMultiaddrs?.() || []).map((ma) => ma.toString()));
|
|
233
|
+
const byTransport = {
|
|
234
|
+
webrtc: all.filter((ma) => ma.includes('/webrtc')),
|
|
235
|
+
tcp: all.filter((ma) => ma.includes('/tcp/') && !ma.includes('/ws')),
|
|
236
|
+
websocket: all.filter((ma) => ma.includes('/ws')),
|
|
237
|
+
};
|
|
238
|
+
const metricsHttpsInfo = options.getMetricsHttpsInfo?.() ?? null;
|
|
239
|
+
sendJson(res, 200, {
|
|
240
|
+
peerId: libp2p?.peerId?.toString?.() || null,
|
|
241
|
+
all,
|
|
242
|
+
byTransport,
|
|
243
|
+
best: {
|
|
244
|
+
webrtc: byTransport.webrtc[0] || null,
|
|
245
|
+
websocket: byTransport.websocket[0] || null,
|
|
246
|
+
tcp: byTransport.tcp[0] || null,
|
|
247
|
+
},
|
|
248
|
+
autoTlsServingZone: metricsHttpsInfo != null && 'autoTlsServingZone' in metricsHttpsInfo
|
|
249
|
+
? metricsHttpsInfo.autoTlsServingZone
|
|
250
|
+
: null,
|
|
251
|
+
metricsHttps: metricsHttpsInfo,
|
|
252
|
+
timestamp: new Date().toISOString(),
|
|
253
|
+
});
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (pinning && pathname === '/pinning/stats' && req.method === 'GET') {
|
|
257
|
+
sendJson(res, 200, pinning.getStats());
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (pinning && pathname === '/pinning/databases' && req.method === 'GET') {
|
|
261
|
+
const filterRaw = firstSearchParam(req.url, ['address', 'dbAddress']);
|
|
262
|
+
const payload = pinning.getDatabases(filterRaw ? { address: filterRaw } : undefined);
|
|
263
|
+
if (filterRaw && payload.total === 0) {
|
|
264
|
+
sendError(res, 404, 'database_not_found', 'Database address not found in relay sync history');
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
sendJson(res, 200, payload);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (pinning && pathname === '/pinning/sync' && req.method === 'POST') {
|
|
271
|
+
try {
|
|
272
|
+
const body = (await readJsonBody(req));
|
|
273
|
+
const fromBody = typeof body?.dbAddress === 'string' ? body.dbAddress.trim() : '';
|
|
274
|
+
const fromQuery = firstSearchParam(req.url, ['dbAddress', 'address']);
|
|
275
|
+
const dbAddress = fromBody || fromQuery;
|
|
276
|
+
if (!dbAddress) {
|
|
277
|
+
sendError(res, 400, 'missing_db_address', 'Missing or invalid dbAddress');
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const result = await pinning.syncDatabase(dbAddress);
|
|
281
|
+
if (!result.ok) {
|
|
282
|
+
sendError(res, 500, 'sync_failed', result.error || 'sync failed');
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
sendJson(res, 200, {
|
|
286
|
+
ok: true,
|
|
287
|
+
dbAddress,
|
|
288
|
+
receivedUpdate: result.receivedUpdate ?? false,
|
|
289
|
+
fallbackScanUsed: result.fallbackScanUsed ?? false,
|
|
290
|
+
extractedMediaCids: result.extractedMediaCids ?? [],
|
|
291
|
+
...(result.coalesced ? { coalesced: true } : {}),
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
const code = error?.code === 'invalid_json' ? 'invalid_json' : 'bad_request';
|
|
296
|
+
sendError(res, 400, code, error?.message || String(error));
|
|
297
|
+
}
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const parsed = parseIpfsRequest(req);
|
|
301
|
+
if (parsed.handled) {
|
|
302
|
+
if (!parsed.ok) {
|
|
303
|
+
sendError(res, parsed.status, parsed.code, parsed.error);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (options.ipfsGateway?.enabled === false) {
|
|
307
|
+
sendError(res, 404, 'content_not_found', 'IPFS gateway is disabled');
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const pinnedResult = pinning?.streamPinnedCid == null ? null : await pinning.streamPinnedCid(parsed.cidStr, parsed.pathWithin);
|
|
311
|
+
if (pinnedResult?.ok) {
|
|
312
|
+
res.statusCode = 200;
|
|
313
|
+
res.setHeader('Content-Type', pinnedResult.contentType || 'application/octet-stream');
|
|
314
|
+
res.setHeader('Cache-Control', 'private, no-store');
|
|
315
|
+
for await (const chunk of pinnedResult.chunks) {
|
|
316
|
+
if (!res.write(chunk)) {
|
|
317
|
+
await new Promise((resolve, reject) => {
|
|
318
|
+
res.once('drain', resolve);
|
|
319
|
+
res.once('error', reject);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
res.end();
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (fallbackMode === 'pinned-only') {
|
|
327
|
+
const status = pinnedResult?.status ?? 404;
|
|
328
|
+
const error = pinnedResult?.error ?? 'Content not pinned locally';
|
|
329
|
+
const code = status === 503 ? 'ipfs_unavailable' : status === 400 ? 'invalid_cid' : 'content_not_found';
|
|
330
|
+
sendError(res, status, code, error);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (pinnedResult != null && pinnedResult.status !== 404) {
|
|
334
|
+
const code = pinnedResult.status === 503 ? 'ipfs_unavailable' : pinnedResult.status === 400 ? 'invalid_cid' : 'internal_error';
|
|
335
|
+
sendError(res, pinnedResult.status, code, pinnedResult.error);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const helia = options.getHelia?.() ?? null;
|
|
339
|
+
if (helia == null) {
|
|
340
|
+
sendError(res, 503, 'ipfs_unavailable', 'Helia gateway is not available');
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
await streamNetworkFallback(res, helia, parsed, catTimeoutMs);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
res.statusCode = 404;
|
|
347
|
+
res.end('Not found');
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
export class PinningHttpServer {
|
|
351
|
+
options;
|
|
352
|
+
server = null;
|
|
353
|
+
constructor(options = {}) {
|
|
354
|
+
this.options = options;
|
|
355
|
+
}
|
|
356
|
+
async start() {
|
|
357
|
+
if (this.server != null)
|
|
358
|
+
return this.server;
|
|
359
|
+
const listener = createPinningHttpRequestHandler(this.options);
|
|
360
|
+
this.server = this.options.tls
|
|
361
|
+
? https.createServer(this.options.tls, listener)
|
|
362
|
+
: http.createServer(listener);
|
|
363
|
+
await new Promise((resolve, reject) => {
|
|
364
|
+
this.server.once('error', reject);
|
|
365
|
+
this.server.listen(this.options.port ?? 9090, this.options.host ?? '0.0.0.0', () => resolve());
|
|
366
|
+
});
|
|
367
|
+
return this.server;
|
|
368
|
+
}
|
|
369
|
+
async stop() {
|
|
370
|
+
if (this.server == null)
|
|
371
|
+
return;
|
|
372
|
+
const server = this.server;
|
|
373
|
+
this.server = null;
|
|
374
|
+
await new Promise((resolve) => {
|
|
375
|
+
server.close(() => resolve());
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
//# sourceMappingURL=pinning-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pinning-http.js","sourceRoot":"","sources":["../../src/http/pinning-http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,9 @@ export type { RelayOptions, RelayRuntime } from './relay.js';
|
|
|
2
2
|
export { startRelay } from './relay.js';
|
|
3
3
|
export type { OrbitdbReplicationServiceApi, OrbitdbReplicationServiceInit } from './services/orbitdb-replication-service.js';
|
|
4
4
|
export { orbitdbReplicationService } from './services/orbitdb-replication-service.js';
|
|
5
|
+
export type { PinningHttpHandlers } from './services/metrics.js';
|
|
6
|
+
export type { ConnectivityDebugProtocolsServiceInit } from './services/connectivity-debug-protocols-service.js';
|
|
7
|
+
export { CONNECTIVITY_BULK_PROTOCOL, CONNECTIVITY_ECHO_PROTOCOL, connectivityDebugProtocolsService, } from './services/connectivity-debug-protocols-service.js';
|
|
8
|
+
export type { Libp2pLike as PinningHttpLibp2pLike, PinningHttpFallbackMode, PinningHttpRequestHandlerOptions, PinningHttpServerOptions, } from './http/pinning-http.js';
|
|
9
|
+
export { PinningHttpServer, createPinningHttpRequestHandler, isManagedPinningHttpPath, } from './http/pinning-http.js';
|
|
5
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,YAAY,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,MAAM,2CAA2C,CAAA;AAC5H,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,YAAY,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,MAAM,2CAA2C,CAAA;AAC5H,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA;AACrF,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAChE,YAAY,EAAE,qCAAqC,EAAE,MAAM,oDAAoD,CAAA;AAC/G,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,iCAAiC,GAClC,MAAM,oDAAoD,CAAA;AAC3D,YAAY,EACV,UAAU,IAAI,qBAAqB,EACnC,uBAAuB,EACvB,gCAAgC,EAChC,wBAAwB,GACzB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,wBAAwB,GACzB,MAAM,wBAAwB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { startRelay } from './relay.js';
|
|
2
2
|
export { orbitdbReplicationService } from './services/orbitdb-replication-service.js';
|
|
3
|
+
export { CONNECTIVITY_BULK_PROTOCOL, CONNECTIVITY_ECHO_PROTOCOL, connectivityDebugProtocolsService, } from './services/connectivity-debug-protocols-service.js';
|
|
4
|
+
export { PinningHttpServer, createPinningHttpRequestHandler, isManagedPinningHttpPath, } from './http/pinning-http.js';
|
|
3
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAA;AAGrF,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,iCAAiC,GAClC,MAAM,oDAAoD,CAAA;AAO3D,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,wBAAwB,GACzB,MAAM,wBAAwB,CAAA"}
|
package/dist/relay.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { type ConnectivityDebugProtocolsServiceInit } from './services/connectivity-debug-protocols-service.js';
|
|
1
2
|
export type RelayOptions = {
|
|
2
3
|
testMode?: boolean;
|
|
3
4
|
storageDir?: string;
|
|
5
|
+
debugProtocols?: ConnectivityDebugProtocolsServiceInit;
|
|
6
|
+
pinningHttp?: {
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
fallbackMode?: 'pinned-only' | 'pinned-first-network-fallback';
|
|
9
|
+
catTimeoutMs?: number;
|
|
10
|
+
};
|
|
4
11
|
};
|
|
5
12
|
export type RelayRuntime = {
|
|
6
13
|
stop: () => Promise<void>;
|
package/dist/relay.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AASA,OAAO,EAAqC,KAAK,qCAAqC,EAAE,MAAM,oDAAoD,CAAA;AAKlJ,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,qCAAqC,CAAA;IACtD,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,YAAY,CAAC,EAAE,aAAa,GAAG,+BAA+B,CAAA;QAC9D,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B,CAAA;AA+HD,wBAAsB,UAAU,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkF/E"}
|