diff --git a/CHANGELOG.md b/CHANGELOG.md index ea30109..efbbc8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.0.1-alpha.35](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.34...v0.0.1-alpha.35) (2024-09-19) + + +### Bug Fixes + +* findPeerWithStoreKey ([94a8b3b](https://github.com/DIG-Network/dig-chia-sdk/commit/94a8b3bb1b181c4675bb709565828c6bbc1467e7)) + ### [0.0.1-alpha.34](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.33...v0.0.1-alpha.34) (2024-09-19) ### [0.0.1-alpha.33](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.32...v0.0.1-alpha.33) (2024-09-19) diff --git a/package-lock.json b/package-lock.json index e5e21fd..0a729cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.34", + "version": "0.0.1-alpha.35", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.34", + "version": "0.0.1-alpha.35", "license": "ISC", "dependencies": { "@dignetwork/datalayer-driver": "^0.1.24", diff --git a/package.json b/package.json index 16d0ad0..162398a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dignetwork/dig-sdk", - "version": "0.0.1-alpha.34", + "version": "0.0.1-alpha.35", "description": "", "type": "commonjs", "main": "./dist/index.js", diff --git a/src/DigNetwork/DigNetwork.ts b/src/DigNetwork/DigNetwork.ts index 950d2a5..7c494ca 100644 --- a/src/DigNetwork/DigNetwork.ts +++ b/src/DigNetwork/DigNetwork.ts @@ -174,11 +174,11 @@ export class DigNetwork { const peerIp = digPeers[0]; const digPeer = new DigPeer(peerIp, storeId); - const storeResponse = await digPeer.contentServer.headStore({ + const storeResponse = await digPeer.propagationServer.headStore({ hasRootHash: rootHash, }); - console.log(peerIp, storeResponse, storeResponse.headers); + console.log(peerIp, storeResponse.headers); if ( storeResponse.success && diff --git a/src/DigNetwork/PropagationServer.ts b/src/DigNetwork/PropagationServer.ts index e0f1c71..995d0a3 100644 --- a/src/DigNetwork/PropagationServer.ts +++ b/src/DigNetwork/PropagationServer.ts @@ -1,12 +1,11 @@ import fs from "fs"; import https from "https"; +import http from 'http'; import { URL } from "url"; import { getOrCreateSSLCerts } from "../utils/ssl"; import { promptCredentials } from "../utils/credentialsUtils"; -import { waitForPromise } from "../utils/spinnerUtils"; import { Wallet } from "../blockchain"; import { Readable } from "stream"; -import { getFilePathFromSha256 } from "../utils/hashUtils"; export class PropagationServer { private ipAddress: string; @@ -93,8 +92,13 @@ export class PropagationServer { } // Method to check if a specific store exists (HEAD request) - public async headStore(): Promise { - const url = `https://${this.ipAddress}:${PropagationServer.port}/${this.storeId}`; + public async headStore(options?: { hasRootHash: string }): Promise<{ success: boolean; headers?: http.IncomingHttpHeaders }> { + let url = `https://${this.ipAddress}:${PropagationServer.port}/${this.storeId}`; + + if (options?.hasRootHash) { + url += `?hasRootHash=${options.hasRootHash}`; + } + return this.head(url); } @@ -387,34 +391,69 @@ export class PropagationServer { } // Helper method to perform HEAD requests - private async head(url: string): Promise { - return new Promise((resolve, reject) => { - const urlObj = new URL(url); - - const options = { - hostname: urlObj.hostname, - port: urlObj.port || PropagationServer.port, - path: urlObj.pathname + urlObj.search, - method: "HEAD", - key: fs.readFileSync(PropagationServer.keyPath), - cert: fs.readFileSync(PropagationServer.certPath), - rejectUnauthorized: false, - }; - - const request = https.request(options, (response) => { - if (response.statusCode === 200) { - resolve(true); - } else { - resolve(false); - } - }); - - request.on("error", (error) => { - console.error(`Request error for ${url}:`, error); - reject(false); - }); - - request.end(); + private async head( + url: string, + maxRedirects: number = 5 + ): Promise<{ success: boolean; headers?: http.IncomingHttpHeaders }> { + return new Promise((resolve, reject) => { + try { + // Parse the input URL + const urlObj = new URL(url); + + const requestOptions = { + hostname: urlObj.hostname, + port: urlObj.port || (urlObj.protocol === "https:" ? 443 : undefined), + path: urlObj.pathname + urlObj.search, + method: "HEAD", + key: fs.readFileSync(PropagationServer.keyPath), + cert: fs.readFileSync(PropagationServer.certPath), + rejectUnauthorized: false, + }; + + const request = https.request(requestOptions, (response) => { + const { statusCode, headers } = response; + + // If status code is 2xx, return success + if (statusCode && statusCode >= 200 && statusCode < 300) { + resolve({ success: true, headers }); + } + // Handle 3xx redirection + else if (statusCode && statusCode >= 300 && statusCode < 400 && headers.location) { + if (maxRedirects > 0) { + let redirectUrl = headers.location; + + // Check if the redirect URL is relative + if (!/^https?:\/\//i.test(redirectUrl)) { + // Resolve the relative URL based on the original URL + redirectUrl = new URL(redirectUrl, url).toString(); + console.log(`Resolved relative redirect to: ${redirectUrl}`); + } else { + console.log(`Redirecting to: ${redirectUrl}`); + } + + // Recursively follow the redirection + this.head(redirectUrl, maxRedirects - 1) + .then(resolve) + .catch(reject); + } else { + reject({ success: false, message: "Too many redirects" }); + } + } else { + // For other status codes, consider it a failure + resolve({ success: false }); + } + }); + + request.on("error", (error) => { + console.error(`Request error for ${url}:`, error); + reject({ success: false }); + }); + + request.end(); + } catch (err) { + console.error(`Invalid URL: ${url}`, err); + reject({ success: false, message: "Invalid URL" }); + } }); }