@libp2p/fetch 3.0.22-6059227cb → 3.0.22-87bc8d4fb
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/dist/index.min.js +1 -1
- package/dist/index.min.js.map +4 -4
- package/dist/src/fetch.d.ts +2 -2
- package/dist/src/fetch.d.ts.map +1 -1
- package/dist/src/fetch.js +78 -50
- package/dist/src/fetch.js.map +1 -1
- package/package.json +12 -10
- package/src/fetch.ts +82 -55
package/dist/src/fetch.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Fetch as FetchInterface, FetchComponents, FetchInit, LookupFunction } from './index.js';
|
|
2
|
-
import type { AbortOptions,
|
|
2
|
+
import type { AbortOptions, PeerId, Startable, IncomingStreamData } from '@libp2p/interface';
|
|
3
3
|
/**
|
|
4
4
|
* A simple libp2p protocol for requesting a value corresponding to a key from a peer.
|
|
5
5
|
* Developers can register one or more lookup function for retrieving the value corresponding to
|
|
@@ -26,7 +26,7 @@ export declare class Fetch implements Startable, FetchInterface {
|
|
|
26
26
|
* responds based on looking up the key in the request via the lookup callback that corresponds
|
|
27
27
|
* to the key's prefix.
|
|
28
28
|
*/
|
|
29
|
-
handleMessage(
|
|
29
|
+
handleMessage(data: IncomingStreamData): Promise<void>;
|
|
30
30
|
/**
|
|
31
31
|
* Given a key, finds the appropriate function for looking up its corresponding value, based on
|
|
32
32
|
* the key's prefix.
|
package/dist/src/fetch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/fetch.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,IAAI,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AACrG,OAAO,KAAK,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/fetch.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,IAAI,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AACrG,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAIpG;;;;;GAKG;AACH,qBAAa,KAAM,YAAW,SAAS,EAAE,cAAc;IACrD,SAAgB,QAAQ,EAAE,MAAM,CAAA;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;IAC7D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;gBAEnB,UAAU,EAAE,eAAe,EAAE,IAAI,GAAE,SAAc;IAS9D,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,mBAAkB;IAEzC,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAkBvB,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAK5B,SAAS,IAAK,OAAO;IAIrB;;OAEG;IACG,KAAK,CAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAwEjH;;;;OAIG;IACG,aAAa,CAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqD7D;;;OAGG;IACH,kBAAkB,CAAE,GAAG,EAAE,MAAM,GAAG;QAAE,EAAE,EAAE,cAAc,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAepF;;;;;;;;;;OAUG;IACH,sBAAsB,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI;IAQrE;;;;;;;;;;OAUG;IACH,wBAAwB,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI;CAWzE"}
|
package/dist/src/fetch.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InvalidMessageError, InvalidParametersError, ProtocolError } from '@libp2p/interface';
|
|
2
|
-
import { pbStream } from '
|
|
1
|
+
import { AbortError, InvalidMessageError, InvalidParametersError, ProtocolError } from '@libp2p/interface';
|
|
2
|
+
import { pbStream } from 'it-protobuf-stream';
|
|
3
3
|
import { setMaxListeners } from 'main-event';
|
|
4
4
|
import { fromString as uint8arrayFromString } from 'uint8arrays/from-string';
|
|
5
5
|
import { toString as uint8arrayToString } from 'uint8arrays/to-string';
|
|
@@ -23,12 +23,21 @@ export class Fetch {
|
|
|
23
23
|
this.components = components;
|
|
24
24
|
this.protocol = `/${init.protocolPrefix ?? 'libp2p'}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`;
|
|
25
25
|
this.lookupFunctions = new Map(); // Maps key prefix to value lookup function
|
|
26
|
-
this.init = init;
|
|
27
26
|
this.handleMessage = this.handleMessage.bind(this);
|
|
27
|
+
this.init = init;
|
|
28
28
|
}
|
|
29
29
|
[Symbol.toStringTag] = '@libp2p/fetch';
|
|
30
30
|
async start() {
|
|
31
|
-
await this.components.registrar.handle(this.protocol,
|
|
31
|
+
await this.components.registrar.handle(this.protocol, (data) => {
|
|
32
|
+
const log = data.connection.log.newScope('fetch');
|
|
33
|
+
void this.handleMessage(data)
|
|
34
|
+
.then(async () => {
|
|
35
|
+
await data.stream.close();
|
|
36
|
+
})
|
|
37
|
+
.catch(err => {
|
|
38
|
+
log.error('error handling message - %e', err);
|
|
39
|
+
});
|
|
40
|
+
}, {
|
|
32
41
|
maxInboundStreams: this.init.maxInboundStreams,
|
|
33
42
|
maxOutboundStreams: this.init.maxOutboundStreams
|
|
34
43
|
});
|
|
@@ -48,28 +57,34 @@ export class Fetch {
|
|
|
48
57
|
if (typeof key === 'string') {
|
|
49
58
|
key = uint8arrayFromString(key);
|
|
50
59
|
}
|
|
60
|
+
const connection = await this.components.connectionManager.openConnection(peer, options);
|
|
61
|
+
const log = connection.log.newScope('fetch');
|
|
62
|
+
let signal = options.signal;
|
|
63
|
+
let stream;
|
|
64
|
+
let onAbort = () => { };
|
|
51
65
|
// create a timeout if no abort signal passed
|
|
52
|
-
if (
|
|
66
|
+
if (signal == null) {
|
|
53
67
|
const timeout = this.init.timeout ?? DEFAULT_TIMEOUT;
|
|
54
|
-
|
|
68
|
+
log.trace('using default timeout of %d ms', timeout);
|
|
69
|
+
signal = AbortSignal.timeout(timeout);
|
|
55
70
|
setMaxListeners(Infinity, signal);
|
|
56
|
-
options = {
|
|
57
|
-
...options,
|
|
58
|
-
signal
|
|
59
|
-
};
|
|
60
71
|
}
|
|
61
|
-
let stream;
|
|
62
72
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
stream = await connection.newStream(this.protocol, {
|
|
74
|
+
signal
|
|
75
|
+
});
|
|
76
|
+
onAbort = () => {
|
|
77
|
+
stream?.abort(new AbortError());
|
|
78
|
+
};
|
|
79
|
+
// make stream abortable
|
|
80
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
66
81
|
log.trace('fetch %m', key);
|
|
67
82
|
const pb = pbStream(stream);
|
|
68
83
|
await pb.write({
|
|
69
84
|
identifier: key
|
|
70
85
|
}, FetchRequest, options);
|
|
71
86
|
const response = await pb.read(FetchResponse, options);
|
|
72
|
-
await
|
|
87
|
+
await pb.unwrap().close(options);
|
|
73
88
|
switch (response.status) {
|
|
74
89
|
case (FetchResponse.StatusCode.OK): {
|
|
75
90
|
log.trace('received status OK for %m', key);
|
|
@@ -94,52 +109,65 @@ export class Fetch {
|
|
|
94
109
|
stream?.abort(err);
|
|
95
110
|
throw err;
|
|
96
111
|
}
|
|
112
|
+
finally {
|
|
113
|
+
signal.removeEventListener('abort', onAbort);
|
|
114
|
+
if (stream != null) {
|
|
115
|
+
await stream.close();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
97
118
|
}
|
|
98
119
|
/**
|
|
99
120
|
* Invoked when a fetch request is received. Reads the request message off the given stream and
|
|
100
121
|
* responds based on looking up the key in the request via the lookup callback that corresponds
|
|
101
122
|
* to the key's prefix.
|
|
102
123
|
*/
|
|
103
|
-
async handleMessage(
|
|
104
|
-
const
|
|
124
|
+
async handleMessage(data) {
|
|
125
|
+
const { stream, connection } = data;
|
|
126
|
+
const log = connection.log.newScope('fetch');
|
|
105
127
|
const signal = AbortSignal.timeout(this.init.timeout ?? DEFAULT_TIMEOUT);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
try {
|
|
129
|
+
const pb = pbStream(stream);
|
|
130
|
+
const request = await pb.read(FetchRequest, {
|
|
131
|
+
signal
|
|
132
|
+
});
|
|
133
|
+
let response;
|
|
134
|
+
const key = uint8arrayToString(request.identifier);
|
|
135
|
+
const lookup = this._getLookupFunction(key);
|
|
136
|
+
if (lookup == null) {
|
|
137
|
+
log.trace('sending status ERROR for %m', request.identifier);
|
|
138
|
+
const errMsg = uint8arrayFromString('No lookup function registered for key');
|
|
139
|
+
response = { status: FetchResponse.StatusCode.ERROR, data: errMsg };
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
log.trace('lookup data with identifier %s', lookup.prefix);
|
|
143
|
+
try {
|
|
144
|
+
const data = await lookup.fn(request.identifier);
|
|
145
|
+
if (data == null) {
|
|
146
|
+
log.trace('sending status NOT_FOUND for %m', request.identifier);
|
|
147
|
+
response = { status: FetchResponse.StatusCode.NOT_FOUND, data: new Uint8Array(0) };
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
log.trace('sending status OK for %m', request.identifier);
|
|
151
|
+
response = { status: FetchResponse.StatusCode.OK, data };
|
|
152
|
+
}
|
|
125
153
|
}
|
|
126
|
-
|
|
127
|
-
log.
|
|
128
|
-
|
|
154
|
+
catch (err) {
|
|
155
|
+
log.error('error during lookup of %m - %e', request.identifier, err);
|
|
156
|
+
const errMsg = uint8arrayFromString(err.message);
|
|
157
|
+
response = { status: FetchResponse.StatusCode.ERROR, data: errMsg };
|
|
129
158
|
}
|
|
130
159
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
160
|
+
await pb.write(response, FetchResponse, {
|
|
161
|
+
signal
|
|
162
|
+
});
|
|
163
|
+
await pb.unwrap().close({
|
|
164
|
+
signal
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
log.error('error answering fetch request - %e', err);
|
|
169
|
+
stream.abort(err);
|
|
136
170
|
}
|
|
137
|
-
await pb.write(response, FetchResponse, {
|
|
138
|
-
signal
|
|
139
|
-
});
|
|
140
|
-
await stream.close({
|
|
141
|
-
signal
|
|
142
|
-
});
|
|
143
171
|
}
|
|
144
172
|
/**
|
|
145
173
|
* Given a key, finds the appropriate function for looking up its corresponding value, based on
|
package/dist/src/fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/fetch.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/fetch",
|
|
3
|
-
"version": "3.0.22-
|
|
3
|
+
"version": "3.0.22-87bc8d4fb",
|
|
4
4
|
"description": "Implementation of the Fetch Protocol",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/protocol-fetch#readme",
|
|
@@ -45,20 +45,22 @@
|
|
|
45
45
|
"doc-check": "aegir doc-check"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@libp2p/interface": "2.11.0-
|
|
49
|
-
"@libp2p/interface-internal": "2.3.19-
|
|
50
|
-
"
|
|
48
|
+
"@libp2p/interface": "2.11.0-87bc8d4fb",
|
|
49
|
+
"@libp2p/interface-internal": "2.3.19-87bc8d4fb",
|
|
50
|
+
"it-protobuf-stream": "^2.0.2",
|
|
51
51
|
"main-event": "^1.0.1",
|
|
52
|
-
"protons-runtime": "^5.
|
|
52
|
+
"protons-runtime": "^5.5.0",
|
|
53
53
|
"uint8arraylist": "^2.4.8",
|
|
54
54
|
"uint8arrays": "^5.1.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@libp2p/crypto": "5.1.8-
|
|
58
|
-
"@libp2p/
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
57
|
+
"@libp2p/crypto": "5.1.8-87bc8d4fb",
|
|
58
|
+
"@libp2p/logger": "5.2.0-87bc8d4fb",
|
|
59
|
+
"@libp2p/peer-id": "5.1.9-87bc8d4fb",
|
|
60
|
+
"aegir": "^47.0.14",
|
|
61
|
+
"it-pair": "^2.0.6",
|
|
62
|
+
"protons": "^7.6.1",
|
|
63
|
+
"sinon": "^20.0.0",
|
|
62
64
|
"sinon-ts": "^2.0.0"
|
|
63
65
|
},
|
|
64
66
|
"sideEffects": false
|
package/src/fetch.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { InvalidMessageError, InvalidParametersError, ProtocolError } from '@libp2p/interface'
|
|
2
|
-
import { pbStream } from '
|
|
1
|
+
import { AbortError, InvalidMessageError, InvalidParametersError, ProtocolError } from '@libp2p/interface'
|
|
2
|
+
import { pbStream } from 'it-protobuf-stream'
|
|
3
3
|
import { setMaxListeners } from 'main-event'
|
|
4
4
|
import { fromString as uint8arrayFromString } from 'uint8arrays/from-string'
|
|
5
5
|
import { toString as uint8arrayToString } from 'uint8arrays/to-string'
|
|
6
6
|
import { PROTOCOL_NAME, PROTOCOL_VERSION } from './constants.js'
|
|
7
7
|
import { FetchRequest, FetchResponse } from './pb/proto.js'
|
|
8
8
|
import type { Fetch as FetchInterface, FetchComponents, FetchInit, LookupFunction } from './index.js'
|
|
9
|
-
import type { AbortOptions, Stream, PeerId, Startable } from '@libp2p/interface'
|
|
9
|
+
import type { AbortOptions, Stream, PeerId, Startable, IncomingStreamData } from '@libp2p/interface'
|
|
10
10
|
|
|
11
11
|
const DEFAULT_TIMEOUT = 10_000
|
|
12
12
|
|
|
@@ -28,15 +28,24 @@ export class Fetch implements Startable, FetchInterface {
|
|
|
28
28
|
this.components = components
|
|
29
29
|
this.protocol = `/${init.protocolPrefix ?? 'libp2p'}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
|
|
30
30
|
this.lookupFunctions = new Map() // Maps key prefix to value lookup function
|
|
31
|
-
this.init = init
|
|
32
|
-
|
|
33
31
|
this.handleMessage = this.handleMessage.bind(this)
|
|
32
|
+
this.init = init
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
readonly [Symbol.toStringTag] = '@libp2p/fetch'
|
|
37
36
|
|
|
38
37
|
async start (): Promise<void> {
|
|
39
|
-
await this.components.registrar.handle(this.protocol,
|
|
38
|
+
await this.components.registrar.handle(this.protocol, (data) => {
|
|
39
|
+
const log = data.connection.log.newScope('fetch')
|
|
40
|
+
|
|
41
|
+
void this.handleMessage(data)
|
|
42
|
+
.then(async () => {
|
|
43
|
+
await data.stream.close()
|
|
44
|
+
})
|
|
45
|
+
.catch(err => {
|
|
46
|
+
log.error('error handling message - %e', err)
|
|
47
|
+
})
|
|
48
|
+
}, {
|
|
40
49
|
maxInboundStreams: this.init.maxInboundStreams,
|
|
41
50
|
maxOutboundStreams: this.init.maxOutboundStreams
|
|
42
51
|
})
|
|
@@ -60,25 +69,33 @@ export class Fetch implements Startable, FetchInterface {
|
|
|
60
69
|
key = uint8arrayFromString(key)
|
|
61
70
|
}
|
|
62
71
|
|
|
72
|
+
const connection = await this.components.connectionManager.openConnection(peer, options)
|
|
73
|
+
const log = connection.log.newScope('fetch')
|
|
74
|
+
let signal = options.signal
|
|
75
|
+
let stream: Stream | undefined
|
|
76
|
+
let onAbort = (): void => {}
|
|
77
|
+
|
|
63
78
|
// create a timeout if no abort signal passed
|
|
64
|
-
if (
|
|
79
|
+
if (signal == null) {
|
|
65
80
|
const timeout = this.init.timeout ?? DEFAULT_TIMEOUT
|
|
66
|
-
|
|
81
|
+
log.trace('using default timeout of %d ms', timeout)
|
|
82
|
+
signal = AbortSignal.timeout(timeout)
|
|
83
|
+
|
|
67
84
|
setMaxListeners(Infinity, signal)
|
|
85
|
+
}
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
try {
|
|
88
|
+
stream = await connection.newStream(this.protocol, {
|
|
71
89
|
signal
|
|
72
|
-
}
|
|
73
|
-
}
|
|
90
|
+
})
|
|
74
91
|
|
|
75
|
-
|
|
92
|
+
onAbort = () => {
|
|
93
|
+
stream?.abort(new AbortError())
|
|
94
|
+
}
|
|
76
95
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
stream = await connection.newStream(this.protocol, options)
|
|
96
|
+
// make stream abortable
|
|
97
|
+
signal.addEventListener('abort', onAbort, { once: true })
|
|
80
98
|
|
|
81
|
-
const log = stream.log.newScope('fetch')
|
|
82
99
|
log.trace('fetch %m', key)
|
|
83
100
|
|
|
84
101
|
const pb = pbStream(stream)
|
|
@@ -87,8 +104,7 @@ export class Fetch implements Startable, FetchInterface {
|
|
|
87
104
|
}, FetchRequest, options)
|
|
88
105
|
|
|
89
106
|
const response = await pb.read(FetchResponse, options)
|
|
90
|
-
|
|
91
|
-
await stream.close(options)
|
|
107
|
+
await pb.unwrap().close(options)
|
|
92
108
|
|
|
93
109
|
switch (response.status) {
|
|
94
110
|
case (FetchResponse.StatusCode.OK): {
|
|
@@ -112,6 +128,11 @@ export class Fetch implements Startable, FetchInterface {
|
|
|
112
128
|
} catch (err: any) {
|
|
113
129
|
stream?.abort(err)
|
|
114
130
|
throw err
|
|
131
|
+
} finally {
|
|
132
|
+
signal.removeEventListener('abort', onAbort)
|
|
133
|
+
if (stream != null) {
|
|
134
|
+
await stream.close()
|
|
135
|
+
}
|
|
115
136
|
}
|
|
116
137
|
}
|
|
117
138
|
|
|
@@ -120,51 +141,57 @@ export class Fetch implements Startable, FetchInterface {
|
|
|
120
141
|
* responds based on looking up the key in the request via the lookup callback that corresponds
|
|
121
142
|
* to the key's prefix.
|
|
122
143
|
*/
|
|
123
|
-
async handleMessage (
|
|
124
|
-
const
|
|
144
|
+
async handleMessage (data: IncomingStreamData): Promise<void> {
|
|
145
|
+
const { stream, connection } = data
|
|
146
|
+
const log = connection.log.newScope('fetch')
|
|
125
147
|
const signal = AbortSignal.timeout(this.init.timeout ?? DEFAULT_TIMEOUT)
|
|
126
148
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
let response: FetchResponse
|
|
133
|
-
const key = uint8arrayToString(request.identifier)
|
|
134
|
-
|
|
135
|
-
const lookup = this._getLookupFunction(key)
|
|
149
|
+
try {
|
|
150
|
+
const pb = pbStream(stream)
|
|
151
|
+
const request = await pb.read(FetchRequest, {
|
|
152
|
+
signal
|
|
153
|
+
})
|
|
136
154
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const errMsg = uint8arrayFromString('No lookup function registered for key')
|
|
140
|
-
response = { status: FetchResponse.StatusCode.ERROR, data: errMsg }
|
|
141
|
-
} else {
|
|
142
|
-
log.trace('lookup data with identifier %s', lookup.prefix)
|
|
155
|
+
let response: FetchResponse
|
|
156
|
+
const key = uint8arrayToString(request.identifier)
|
|
143
157
|
|
|
144
|
-
|
|
145
|
-
const data = await lookup.fn(request.identifier)
|
|
158
|
+
const lookup = this._getLookupFunction(key)
|
|
146
159
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
} else {
|
|
151
|
-
log.trace('sending status OK for %m', request.identifier)
|
|
152
|
-
response = { status: FetchResponse.StatusCode.OK, data }
|
|
153
|
-
}
|
|
154
|
-
} catch (err: any) {
|
|
155
|
-
log.error('error during lookup of %m - %e', request.identifier, err)
|
|
156
|
-
const errMsg = uint8arrayFromString(err.message)
|
|
160
|
+
if (lookup == null) {
|
|
161
|
+
log.trace('sending status ERROR for %m', request.identifier)
|
|
162
|
+
const errMsg = uint8arrayFromString('No lookup function registered for key')
|
|
157
163
|
response = { status: FetchResponse.StatusCode.ERROR, data: errMsg }
|
|
164
|
+
} else {
|
|
165
|
+
log.trace('lookup data with identifier %s', lookup.prefix)
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
const data = await lookup.fn(request.identifier)
|
|
169
|
+
|
|
170
|
+
if (data == null) {
|
|
171
|
+
log.trace('sending status NOT_FOUND for %m', request.identifier)
|
|
172
|
+
response = { status: FetchResponse.StatusCode.NOT_FOUND, data: new Uint8Array(0) }
|
|
173
|
+
} else {
|
|
174
|
+
log.trace('sending status OK for %m', request.identifier)
|
|
175
|
+
response = { status: FetchResponse.StatusCode.OK, data }
|
|
176
|
+
}
|
|
177
|
+
} catch (err: any) {
|
|
178
|
+
log.error('error during lookup of %m - %e', request.identifier, err)
|
|
179
|
+
const errMsg = uint8arrayFromString(err.message)
|
|
180
|
+
response = { status: FetchResponse.StatusCode.ERROR, data: errMsg }
|
|
181
|
+
}
|
|
158
182
|
}
|
|
159
|
-
}
|
|
160
183
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
184
|
+
await pb.write(response, FetchResponse, {
|
|
185
|
+
signal
|
|
186
|
+
})
|
|
164
187
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
188
|
+
await pb.unwrap().close({
|
|
189
|
+
signal
|
|
190
|
+
})
|
|
191
|
+
} catch (err: any) {
|
|
192
|
+
log.error('error answering fetch request - %e', err)
|
|
193
|
+
stream.abort(err)
|
|
194
|
+
}
|
|
168
195
|
}
|
|
169
196
|
|
|
170
197
|
/**
|