diff --git a/config.js b/config.js index a80911cc47cf3888babbda94733fc943bdeec417..69e541f1e32c5d6d630111a7a05d8af98adafd26 100644 --- a/config.js +++ b/config.js @@ -13,8 +13,18 @@ self.SamizdatConfig.plugins = { 'cache':{}, 'any-of': { plugins: { - 'gateway-ipns':{ - ipnsPubkey: 'QmYGVgGGfD5N4Xcc78CcMJ99dKcH6K6myhd4Uenv5yJwiJ' + 'alt-fetch':{ + // configuring the alternate endpoints plugin to use IPNS gateways + // + // NOTICE: we cannot use gateways that use hash directly in the (sub)domain: + // https://github.com/node-fetch/node-fetch/issues/260 + endpoints: [ + 'https://ninetailed.ninja/ipns/QmYGVgGGfD5N4Xcc78CcMJ99dKcH6K6myhd4Uenv5yJwiJ/', // Russia + 'https://10.via0.com/ipns/QmYGVgGGfD5N4Xcc78CcMJ99dKcH6K6myhd4Uenv5yJwiJ/', // USA + 'https://ipfs.sloppyta.co/ipns/QmYGVgGGfD5N4Xcc78CcMJ99dKcH6K6myhd4Uenv5yJwiJ/', // UK + 'https://gateway.temporal.cloud/ipns/QmYGVgGGfD5N4Xcc78CcMJ99dKcH6K6myhd4Uenv5yJwiJ/', // Germany + 'https://ipfs.best-practice.se/ipns/QmYGVgGGfD5N4Xcc78CcMJ99dKcH6K6myhd4Uenv5yJwiJ/' // Sweden + ] }, 'gun-ipfs': { gunPubkey: 'WUK5ylwqqgUorceQRa84qfbBFhk7eNRDUoPbGK05SyE.-yohFhTzWPpDT-UDMuKGgemOUrw_cMMYWpy6plILqrg' diff --git a/debug.html b/debug.html index 0e1bbb5afeed3a0420e3f2a92aa1a5a448501725..bbb1db7b62c6e5ffb437307527cc2a06ee6a9504 100644 --- a/debug.html +++ b/debug.html @@ -12,7 +12,7 @@ <script src="./lib/ipfs.js"></script> <script src="./plugins/fetch.js"></script> <script src="./plugins/cache.js"></script> - <script src="./plugins/gateway-ipns.js"></script> + <script src="./plugins/alt-fetch.js"></script> <script src="./plugins/gun-ipfs.js"></script> <h1>Samizdat</h1> diff --git a/plugins/gateway-ipns.js b/plugins/alt-fetch.js similarity index 60% rename from plugins/gateway-ipns.js rename to plugins/alt-fetch.js index c192d002f1eb0c80a500bba0f21ab824b720e540..2a291a02ce8bd4ebf97e32dd3a17240723754365 100644 --- a/plugins/gateway-ipns.js +++ b/plugins/alt-fetch.js @@ -1,5 +1,5 @@ /* ========================================================================= *\ -|* === HTTP(S) fetch() from IPNS via known public gateways === *| +|* === HTTP(S) fetch() from alternative endpoints === *| \* ========================================================================= */ /** @@ -19,33 +19,41 @@ // sane defaults let defaultConfig = { - // the pubkey of the preconfigured IPNS node; always needs to be set in config.js - ipnsPubkey: null, - // some default IPFS gateways to use + // name of this plugin + // should not be changed + name: "alt-fetch", + // endpoints to use + // + // they have to respond to requests formatted like: + // <endpoint-url>/<path> + // + // let's say the endpoint is: + // https://example.com/api/endpoint/ + // ...and that we are trying to get: + // <original-domain>/some/path/img.png + // + // the endpoint is supposed to return the expected image + // when this URL is requested: + // https://example.com/api/endpoint/some/path/img.png + // + // this has to be explicitly configured by the website admin + endpoints: [], + + // how many simultaneous connections to different endpoints do we want // - // important: - // we cannot use gateways that use hash directly in the (sub)domain: - // https://github.com/node-fetch/node-fetch/issues/260 - ipfsGateways: [ - 'https://ninetailed.ninja/ipns/', // Russia - 'https://10.via0.com/ipns/', // USA - 'https://ipfs.sloppyta.co/ipns/', // UK - 'https://gateway.temporal.cloud/ipns/', // Germany - 'https://ipfs.best-practice.se/ipns/' // Sweden - ], - // how many simultaneous connections to gateways we want // more concurrency means higher chance of a request succeeding - // but uses morebandwidth and other resources; - // 3 seems a reasonable default + // but uses more bandwidth and other resources; + // + // 3 seems to be a reasonable default concurrency: 3 } // merge the defaults with settings from SamizdatConfig - let config = {...defaultConfig, ...self.SamizdatConfig.plugins["gateway-ipns"]} + let config = {...defaultConfig, ...self.SamizdatConfig.plugins[defaultConfig.name]} - // reality check: Gun pubkey needs to be set to a non-empty string - if (typeof(config.ipnsPubkey) !== "string" || config.ipnsPubkey === "") { - let err = new Error("ipnsPubkey not confgured") + // reality check: endpoints need to be set to an array of non-empty strings + if (typeof(config.endpoints) !== "object" || !Array.isArray(config.endpoints)) { + let err = new Error("endpoints not confgured") console.error(err) throw err } @@ -54,35 +62,35 @@ /** * getting content using regular HTTP(S) fetch() */ - let fetchContentFromGatewayIPNS = (url) => { + let fetchContentFromAlternativeEndpoints = (url) => { - // we're going to try a random gateway and building an URL of the form: - // https://<gateway_address>/<pubkey>/<rest_of_URL> - var ipnsUrl = config.ipnsPubkey + url.replace(/https?:\/\/[^/]+/, '') + // we're going to try a random endpoint and building an URL of the form: + // https://<endpoint_address>/<pubkey>/<rest_of_URL> + var path = url.replace(/https?:\/\/[^/]+\//, '') - // we don't want to modify the original gateways array - var sourceGateways = [...config.ipfsGateways] + // we don't want to modify the original endpoints array + var sourceEndpoints = [...config.endpoints] // if we have fewer than the configured concurrency, use all of them - if (sourceGateways.length <= config.concurrency) { - var useGateways = sourceGateways - // otherwise get `config.concurrency` gateways at random + if (sourceEndpoints.length <= config.concurrency) { + var useEndpoints = sourceEndpoints + // otherwise get `config.concurrency` endpoints at random } else { - var useGateways = new Array() - while (useGateways.length < config.concurrency) { + var useEndpoints = new Array() + while (useEndpoints.length < config.concurrency) { // put in the address while we're at it - useGateways.push( - sourceGateways - .splice(Math.floor(Math.random() * sourceGateways.length), 1)[0] + ipnsUrl + useEndpoints.push( + sourceEndpoints + .splice(Math.floor(Math.random() * sourceEndpoints.length), 1)[0] + path ) } } // debug log - console.log(`Samizdat: gateway IPNS fetching:\n ${useGateways.join('\n ')}`) + console.log(`Samizdat: fetching from alternative endpoints:\n ${useEndpoints.join('\n ')}`) return Promise.any( - useGateways.map( + useEndpoints.map( u=>fetch(u, {cache: "reload"}) )) .then((response) => { @@ -107,7 +115,7 @@ }); // add the X-Samizdat-* headers to the mix - init.headers['X-Samizdat-Method'] = 'gateway-ipns' + init.headers['X-Samizdat-Method'] = config.name // we will not have it most of the time, due to CORS rules: // https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header @@ -132,10 +140,10 @@ // and add ourselves to it // with some additional metadata self.SamizdatPlugins.push({ - name: 'gateway-ipns', - description: 'HTTP(S) fetch() from IPNS via known public gateways', + name: config.name, + description: 'HTTP(S) fetch() using alternative endpoints', version: 'COMMIT_UNKNOWN', - fetch: fetchContentFromGatewayIPNS + fetch: fetchContentFromAlternativeEndpoints }) // done with not poluting the global namespace diff --git a/plugins/any-of.js b/plugins/any-of.js index 6ce82dd82a1ef0a9dbac3b6f858e7486e98c4a62..2b5c823346bed1e49d506452d69c896f714736cc 100644 --- a/plugins/any-of.js +++ b/plugins/any-of.js @@ -17,7 +17,7 @@ let defaultConfig = { // list of plugins to run simultaneously plugins: { - "gateway-ipns": {}, + "alt-fetch": {}, "gun-ipfs": {} } } diff --git a/service-worker.js b/service-worker.js index 13b30147c4278f653e86fc93dd7e6bd1febf2d73..fded91ad2cedc9705341ff08e0af5c4079080046 100644 --- a/service-worker.js +++ b/service-worker.js @@ -63,7 +63,7 @@ if (typeof self.SamizdatConfig !== 'object' || self.SamizdatConfig === null) { plugins: { 'fetch':{}, 'cache':{}, - 'gateway-ipns':{}, + 'alt-fetch':{}, 'gun-ipfs':{} } }