-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: direct fetch for HTTP retrievals
When the retrieving the content using the Trustless HTTP Gateway protocol ("http"), fetch the content directly from the provider, do not use Lassie. This should give us better visibility into various error statuses returned by providers, e.g. 429 Too Many Requests, which Lassie converts to generic 502 Bad Gateway error. List of synthetic status codes corresponding to different errors we may encounter along the new codepath: - 900 - unknown error (fallback) - 901 - provider's multiaddr is not "tcp" - 902 - provider's multiaddr is not "https" - 903 - provider's multiaddr has too many parts - 911 - provider's hostname cannot be resolved via DNS - 912 - TCP connection error - 921 - CID uses an unsupported hash algorithm - 922 - payload's hash does not match the CID - 923 - provider returned unexpected blocks in the CAR response Signed-off-by: Miroslav Bajtoš <[email protected]>
- Loading branch information
Showing
7 changed files
with
8,346 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,11 @@ | |
export { encodeHex } from 'https://deno.land/[email protected]/encoding/hex.ts' | ||
export { decodeBase64 } from 'https://deno.land/[email protected]/encoding/base64.ts' | ||
export { decode as decodeVarint } from 'https://deno.land/x/[email protected]/varint.ts' | ||
|
||
// Deno Bundle does not support npm dependencies, we have to load the via CDN | ||
export { CarBlockIterator } from 'https://cdn.skypack.dev/@ipld/[email protected]/?dts' | ||
export { | ||
UnsupportedHashError, | ||
HashMismatchError, | ||
validateBlock | ||
} from 'https://cdn.skypack.dev/@web3-storage/[email protected]/?dts' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/** | ||
* @param {string} addr Multiaddr, e.g. `/ip4/127.0.0.1/tcp/80/http` | ||
* @returns {string} Parsed URI, e.g. `http://127.0.0.1:80` | ||
*/ | ||
export function multiaddrToHttpUri (addr) { | ||
const [, hostType, hostValue, ipProtocol, port, scheme, ...rest] = addr.split('/') | ||
|
||
if (ipProtocol !== 'tcp') { | ||
throw Object.assign( | ||
new Error(`Cannot parse "${addr}": unsupported protocol "${ipProtocol}"`), | ||
{ code: 'UNSUPPORTED_MULTIADDR_PROTO' } | ||
) | ||
} | ||
|
||
if (scheme !== 'http' && scheme !== 'https') { | ||
throw Object.assign( | ||
new Error(`Cannot parse "${addr}": unsupported scheme "${scheme}"`), | ||
{ code: 'UNSUPPORTED_MULTIADDR_SCHEME' } | ||
) | ||
} | ||
|
||
if (rest.length) { | ||
throw Object.assign( | ||
new Error(`Cannot parse "${addr}": too many parts`), | ||
{ code: 'MULTIADDR_HAS_TOO_MANY_PARTS' } | ||
) | ||
} | ||
|
||
return `${scheme}://${getUriHost(hostType, hostValue)}${buildUriPort(scheme, port)}` | ||
} | ||
|
||
function getUriHost (hostType, hostValue) { | ||
switch (hostType) { | ||
case 'ip4': | ||
case 'dns': | ||
case 'dns4': | ||
case 'dns6': | ||
return hostValue | ||
case 'ip6': | ||
return `[${hostValue}]` | ||
} | ||
} | ||
|
||
function buildUriPort (scheme, port) { | ||
if (scheme === 'http' && port === '80') return '' | ||
if (scheme === 'https' && port === '443') return '' | ||
return `:${port}` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
import './test/ipni-client.test.js' | ||
import './test/miner-info.test.js' | ||
import './test/multiaddr.test.js' | ||
|
||
import './test/integration.js' | ||
import './test/spark.js' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { test } from 'zinnia:test' | ||
import { assertEquals, assertThrows } from 'zinnia:assert' | ||
import { multiaddrToHttpUri } from '../lib/multiaddr.js' | ||
|
||
const HAPPY_CASES = [ | ||
['/ip4/127.0.0.1/tcp/80/http', 'http://127.0.0.1'], | ||
['/ip4/127.0.0.1/tcp/8080/http', 'http://127.0.0.1:8080'], | ||
['/ip4/127.0.0.1/tcp/443/https', 'https://127.0.0.1'], | ||
['/ip4/127.0.0.1/tcp/8080/https', 'https://127.0.0.1:8080'], | ||
['/dns/meridian.space/tcp/8080/http', 'http://meridian.space:8080'], | ||
['/dns4/meridian.space/tcp/8080/http', 'http://meridian.space:8080'], | ||
['/dns6/meridian.space/tcp/8080/http', 'http://meridian.space:8080'] | ||
] | ||
|
||
for (const [multiaddr, expectedUri] of HAPPY_CASES) { | ||
test(`parse ${multiaddr}`, () => { | ||
const uri = multiaddrToHttpUri(multiaddr) | ||
assertEquals(uri, expectedUri) | ||
}) | ||
} | ||
|
||
const ERROR_CASES = [ | ||
['/ip4/127.0.0.1/tcp/80', 'Cannot parse "/ip4/127.0.0.1/tcp/80": unsupported scheme "undefined"'], | ||
['/ip4/127.0.0.1/udp/90', 'Cannot parse "/ip4/127.0.0.1/udp/90": unsupported protocol "udp"'], | ||
['/ip4/127.0.0.1/tcp/8080/http/p2p/pubkey', 'Cannot parse "/ip4/127.0.0.1/tcp/8080/http/p2p/pubkey": too many parts'] | ||
] | ||
|
||
for (const [multiaddr, expectedError] of ERROR_CASES) { | ||
test(`parse ${multiaddr}`, () => { | ||
const err = assertThrows(() => multiaddrToHttpUri(multiaddr)) | ||
assertEquals(err.message, expectedError) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.