Skip to content

Commit

Permalink
feat: Implementing Trustless Server Checks (#310)
Browse files Browse the repository at this point in the history
  • Loading branch information
whizzzkid authored Oct 12, 2022
1 parent 1bcda7c commit 4a2c926
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 4 deletions.
9 changes: 8 additions & 1 deletion src/GatewayNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { URL } from 'url-ponyfill'
import { Cors } from './Cors'
import { Flag } from './Flag'
import { Origin } from './Origin'
import { Trustless } from './Trustless'
import type { Results } from './Results'
import { Status } from './Status'
import { UiComponent } from './UiComponent'
Expand All @@ -18,6 +19,7 @@ class GatewayNode extends UiComponent /* implements Checkable */ {
status: Status
cors: Cors
origin: Origin
trustless: Trustless
link: HTMLDivElement & { url?: URL }
flag: Flag
took: HTMLDivElement
Expand All @@ -43,6 +45,9 @@ class GatewayNode extends UiComponent /* implements Checkable */ {
this.origin = new Origin(this)
this.tag.append(this.origin.tag)

this.trustless = new Trustless(this)
this.tag.append(this.trustless.tag)

this.link = document.createElement('div')
const gatewayAndHash = gateway.replace(':hash', HASH_TO_TEST)
this.link.url = new URL(gatewayAndHash)
Expand Down Expand Up @@ -72,7 +77,9 @@ class GatewayNode extends UiComponent /* implements Checkable */ {
// this.flag.check().then(() => log.debug(this.gateway, 'Flag success')),
this.status.check().then(() => log.debug(this.gateway, 'Status success')).then(this.onSuccessfulCheck.bind(this)),
this.cors.check().then(() => log.debug(this.gateway, 'CORS success')).then(this.onSuccessfulCheck.bind(this)),
this.origin.check().then(() => log.debug(this.gateway, 'Origin success')).then(this.onSuccessfulCheck.bind(this))
this.origin.check().then(() => log.debug(this.gateway, 'Origin success')).then(this.onSuccessfulCheck.bind(this)),
this.trustless.check().then(
() => log.debug(this.gateway, 'Trustless success')).then(this.onSuccessfulCheck.bind(this))
]

// we care only about the fastest method to return a success
Expand Down
2 changes: 1 addition & 1 deletion src/Tag.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TagStatus } from './TagStatus'

type TagClasses = 'Status' | 'Node' | 'Cors' | 'Origin' | 'Flag'
type TagClasses = 'Status' | 'Node' | 'Cors' | 'Origin' | 'Flag' | 'Trustless'

type TagContent = TagStatus

Expand Down
56 changes: 56 additions & 0 deletions src/Trustless.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import fetchPonyfill from 'fetch-ponyfill'

import { CheckBase } from './CheckBase'
import { HASH_TO_TEST, TRUSTLESS_RESPONSE_TYPES } from './constants'
import type { GatewayNode } from './GatewayNode'

import { Log } from './Log'

const { fetch } = fetchPonyfill()

const log = new Log('Trustless')

class Trustless extends CheckBase implements Checkable {
_className = 'Trustless'
_tagName = 'div'
constructor (protected parent: GatewayNode) {
super(parent, 'div', 'Trustless')
}

async check (): Promise<void> {
const now = Date.now()
const gatewayAndHash = this.parent.gateway.replace(':hash', HASH_TO_TEST)
this.parent.tag.classList.add('trustless')
try {
const trustlessResponseTypesTests = await Promise.all(TRUSTLESS_RESPONSE_TYPES.map(
async (trustlessTypes): Promise<boolean> => {
const testUrl = `${gatewayAndHash}?format=${trustlessTypes}&now=${now}#x-ipfs-companion-no-redirect`
const response = await fetch(testUrl)
return Boolean(response.headers.get('Content-Type')?.includes(`application/vnd.ipld.${trustlessTypes}`))
}
))

if (!trustlessResponseTypesTests.includes(false)) {
this.tag.win()
} else {
log.debug('The response type did not match the expected type')
this.onerror()
throw new Error(`URL '${gatewayAndHash} does not support Trustless`)
}
} catch (err) {
log.error(err)
this.onerror()
throw err
}
}

checked (): void {
log.warn('Not implemented yet')
}

onerror (): void {
this.tag.err()
}
}

export { Trustless }
4 changes: 3 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ const HASH_TO_TEST = 'bafybeifx7yeb55armcsxwwitkymga5xf53dxiarykms3ygqic223w5sk3
const IMG_HASH = 'bafybeibwzifw52ttrkqlikfzext5akxu7lz4xiwjgwzmqcpdzmp3n5vnbe' // 1x1.png
// const IFRAME_HASH = 'bafkreifx3g6bkkwl7b4v43lvcqfo5vshbiehuvmpky2zayhfpg5qj7y3ca'
const HASH_STRING = 'Hello from IPFS Gateway Checker'
const TRUSTLESS_RESPONSE_TYPES = ['raw', 'car']

export {
HASH_STRING,
HASH_TO_TEST,
// IFRAME_HASH,
IMG_HASH
IMG_HASH,
TRUSTLESS_RESPONSE_TYPES
}
1 change: 1 addition & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ <h1 class='f3 fw2 montserrat aqua ttu ma0'>Public Gateways</h1>
<div class="Status" title="Online status: is it possible to read data?" style="cursor: help">Online</div>
<div class="Cors" title="Allows Cross-Origin Resource Sharing (CORS fetch)"><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#The_HTTP_response_headers" target="_blank">CORS</a></div>
<div class="Origin" title="Provides Origin Isolation (Subdomain Gateway)"><a href="https://docs.ipfs.io/how-to/address-ipfs-on-web/#subdomain-gateway" target="_blank">Origin</a></div>
<div class="Trustless" title="Supports Trustless Gateway Specification"><a href="https://github.com/ipfs/specs/blob/main/http-gateways/TRUSTLESS_GATEWAY.md" target="_blank">Trustless</a></div>
<div class="Flag">Country</div>
<div class="Link">Hostname</div>
<div class="Took">ΔT</div>
Expand Down
7 changes: 6 additions & 1 deletion src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ div.Node a, div#origin-warning a {
div.Node div.Status,
div.Node div.Cors,
div.Node div.Origin,
div.Node div.Trustless,
div.Node div.Flag {
width: 5em;
width: 6em;
text-align: center;
margin: 0 0.5em;
user-select: none;
Expand All @@ -93,6 +94,10 @@ div.Node div.Took {
font-style: italic;
}

div.Node.trustless div.Trustless {
margin: 0 1.3em;
}

div.Node.origin div.Link::after {
content: " 💚"
}
Expand Down

0 comments on commit 4a2c926

Please sign in to comment.