fix hns resolver
This commit is contained in:
parent
02b77cfbab
commit
b70d4f143e
|
@ -1,3 +1,4 @@
|
||||||
|
const url = require("url");
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const proxy = require("express-http-proxy");
|
const proxy = require("express-http-proxy");
|
||||||
const { NodeClient } = require("hs-client");
|
const { NodeClient } = require("hs-client");
|
||||||
|
@ -18,14 +19,15 @@ const clientOptions = {
|
||||||
};
|
};
|
||||||
const client = new NodeClient(clientOptions);
|
const client = new NodeClient(clientOptions);
|
||||||
|
|
||||||
const resolveDomain = async (name) => {
|
const startsWithSkylinkRegExp = /^[a-zA-Z0-9_-]{46}/;
|
||||||
|
|
||||||
|
const getDomainRecords = async (name) => {
|
||||||
const response = await client.execute("getnameresource", [name]);
|
const response = await client.execute("getnameresource", [name]);
|
||||||
|
const records = response?.records ?? null;
|
||||||
|
|
||||||
if (!response) throw new Error("API not responding");
|
console.log(`${name} => ${JSON.stringify(records)}`);
|
||||||
|
|
||||||
console.log(`${name} => ${JSON.stringify(response.records)}`);
|
return records;
|
||||||
|
|
||||||
return response;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const findSkylinkRecord = (records) => {
|
const findSkylinkRecord = (records) => {
|
||||||
|
@ -38,9 +40,12 @@ const getSkylinkFromRecord = (record) => {
|
||||||
|
|
||||||
const resolveDomainHandler = async (req, res) => {
|
const resolveDomainHandler = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const response = await resolveDomain(req.params.name);
|
const records = await getDomainRecords(req.params.name);
|
||||||
const record = findSkylinkRecord(response.records);
|
if (!records) return res.status(404).send(`No records found for ${req.params.name}`);
|
||||||
if (!record) return res.status(404).send(`No skylink found for ${req.params.name}`);
|
|
||||||
|
const record = findSkylinkRecord(records);
|
||||||
|
if (!record) throw new Error(`No skylink found in dns records of ${req.params.name}`);
|
||||||
|
|
||||||
const skylink = getSkylinkFromRecord(record);
|
const skylink = getSkylinkFromRecord(record);
|
||||||
return res.json({ skylink });
|
return res.json({ skylink });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -48,14 +53,12 @@ const resolveDomainHandler = async (req, res) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const SIA_LINK_RE = /^([a-zA-Z0-9-_]{46}.*)$/;
|
|
||||||
|
|
||||||
// Checks if the given string is a valid Sia link.
|
// Checks if the given string is a valid Sia link.
|
||||||
function isValidSkylink(link) {
|
function isValidSkylink(link) {
|
||||||
if (!link || link.length === 0) {
|
if (!link || link.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Boolean(link.match(SIA_LINK_RE));
|
return Boolean(link.match(startsWithSkylinkRegExp));
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = express();
|
const server = express();
|
||||||
|
@ -63,19 +66,34 @@ const server = express();
|
||||||
server.use(
|
server.use(
|
||||||
"/hns/:name",
|
"/hns/:name",
|
||||||
proxy("nginx", {
|
proxy("nginx", {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
userResHeaderDecorator(headers, userReq, userRes, proxyReq, proxyRes) {
|
||||||
|
if (headers.location && headers.location.match(startsWithSkylinkRegExp)) {
|
||||||
|
headers.location = headers.location.replace(startsWithSkylinkRegExp, `/hns/${userReq.params.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
proxyReqPathResolver: async (req) => {
|
proxyReqPathResolver: async (req) => {
|
||||||
const response = await resolveDomain(req.params.name);
|
const records = await getDomainRecords(req.params.name);
|
||||||
const record = findSkylinkRecord(response.records);
|
if (!records) throw new Error(`No records found for ${req.params.name}`);
|
||||||
if (!record) throw new Error(`No skylink found for ${req.params.name}`);
|
|
||||||
|
const record = findSkylinkRecord(records);
|
||||||
|
if (!record) throw new Error(`No skylink found in dns records of ${req.params.name}`);
|
||||||
|
|
||||||
const skylink = getSkylinkFromRecord(record);
|
const skylink = getSkylinkFromRecord(record);
|
||||||
|
const basepath = url.resolve("/", skylink); // make the url absolute
|
||||||
|
const subpath = req.url.slice(1); // drop the leading slash
|
||||||
|
|
||||||
// if this is exact domain call, do not append anything to skylink entry
|
// if the skylink from handshake does not contain a subpath but subpath
|
||||||
if (req.url === "" || req.url === "/") return `/${skylink}`;
|
// is defined in request, join the skylink and subpath together (do not
|
||||||
|
// use url.resolve because it will replace skylink with subapth thinking
|
||||||
|
// it is relative)
|
||||||
|
if (skylink.length === 46 && subpath) {
|
||||||
|
return `${basepath}/${subpath}`;
|
||||||
|
}
|
||||||
|
|
||||||
// drop any index.html or trailing slash from the skylink entry
|
return url.resolve(basepath, subpath);
|
||||||
const path = skylink.split("/").slice(0, -1).join("/");
|
|
||||||
|
|
||||||
return `/${path}${req.url}`;
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
Reference in New Issue