Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae0f9447ea | ||
|
|
972b6c7f22 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "litek",
|
"name": "litek",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.9",
|
"version": "0.0.10",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -41,6 +41,26 @@ const Tool: FC = () => {
|
|||||||
const [results, setResults] = useState<DNSRecord[]>([]);
|
const [results, setResults] = useState<DNSRecord[]>([]);
|
||||||
const [queryTime, setQueryTime] = useState<number>(0);
|
const [queryTime, setQueryTime] = useState<number>(0);
|
||||||
|
|
||||||
|
const handleDomainBlur = () => {
|
||||||
|
if (!domain.trim()) return;
|
||||||
|
|
||||||
|
let input = domain.trim();
|
||||||
|
let cleanDomain = input;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to parse as URL
|
||||||
|
const url = new URL(input.startsWith('http') ? input : `https://${input}`);
|
||||||
|
cleanDomain = url.hostname;
|
||||||
|
} catch {
|
||||||
|
// If parsing fails, fallback to manual cleanup
|
||||||
|
cleanDomain = input.replace(/^https?:\/\//, "").split("/")[0].split(":")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleanDomain !== input) {
|
||||||
|
setDomain(cleanDomain);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const queryDNS = async () => {
|
const queryDNS = async () => {
|
||||||
if (!domain.trim()) {
|
if (!domain.trim()) {
|
||||||
toast.error("Please enter a domain name");
|
toast.error("Please enter a domain name");
|
||||||
@@ -58,7 +78,7 @@ const Tool: FC = () => {
|
|||||||
const queries = DNS_RECORD_TYPES.map((recordType) =>
|
const queries = DNS_RECORD_TYPES.map((recordType) =>
|
||||||
fetch(
|
fetch(
|
||||||
`https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(
|
`https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(
|
||||||
domain
|
domain.trim()
|
||||||
)}&type=${recordType.value}`,
|
)}&type=${recordType.value}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
@@ -127,6 +147,7 @@ const Tool: FC = () => {
|
|||||||
placeholder="e.g. example.com"
|
placeholder="e.g. example.com"
|
||||||
value={domain}
|
value={domain}
|
||||||
onChange={(e) => setDomain(e.target.value)}
|
onChange={(e) => setDomain(e.target.value)}
|
||||||
|
onBlur={handleDomainBlur}
|
||||||
onKeyPress={handleKeyPress}
|
onKeyPress={handleKeyPress}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -36,6 +36,27 @@ const Tool: FC = () => {
|
|||||||
const seqRef = useRef<number>(0);
|
const seqRef = useRef<number>(0);
|
||||||
const resultsContainerRef = useRef<HTMLDivElement>(null);
|
const resultsContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const handleUrlBlur = () => {
|
||||||
|
if (!url.trim()) return;
|
||||||
|
|
||||||
|
let input = url.trim();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to parse as URL
|
||||||
|
const parsedUrl = new URL(input.startsWith('http') ? input : `https://${input}`);
|
||||||
|
const normalizedUrl = parsedUrl.toString();
|
||||||
|
|
||||||
|
if (normalizedUrl !== input) {
|
||||||
|
setUrl(normalizedUrl);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// If parsing fails, add https:// prefix
|
||||||
|
if (!input.startsWith("http://") && !input.startsWith("https://")) {
|
||||||
|
setUrl(`https://${input}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const ping = async () => {
|
const ping = async () => {
|
||||||
if (!url.trim()) {
|
if (!url.trim()) {
|
||||||
toast.error("Please enter a URL");
|
toast.error("Please enter a URL");
|
||||||
@@ -43,12 +64,7 @@ const Tool: FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const seq = ++seqRef.current;
|
const seq = ++seqRef.current;
|
||||||
let targetUrl = url.trim();
|
const targetUrl = url.trim();
|
||||||
|
|
||||||
// If no protocol prefix, default to https://
|
|
||||||
if (!targetUrl.startsWith("http://") && !targetUrl.startsWith("https://")) {
|
|
||||||
targetUrl = `https://${targetUrl}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
|
|
||||||
@@ -177,6 +193,7 @@ const Tool: FC = () => {
|
|||||||
placeholder="e.g. example.com or https://example.com"
|
placeholder="e.g. example.com or https://example.com"
|
||||||
value={url}
|
value={url}
|
||||||
onChange={(e) => setUrl(e.target.value)}
|
onChange={(e) => setUrl(e.target.value)}
|
||||||
|
onBlur={handleUrlBlur}
|
||||||
disabled={running}
|
disabled={running}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -142,18 +142,34 @@ const Tool: FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleUrlBlur = () => {
|
||||||
|
if (!url.trim()) return;
|
||||||
|
|
||||||
|
let input = url.trim();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to parse as URL
|
||||||
|
const parsedUrl = new URL(input.startsWith('http') ? input : `https://${input}`);
|
||||||
|
const normalizedUrl = parsedUrl.toString();
|
||||||
|
|
||||||
|
if (normalizedUrl !== input) {
|
||||||
|
setUrl(normalizedUrl);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// If parsing fails, add https:// prefix
|
||||||
|
if (!input.startsWith("http://") && !input.startsWith("https://")) {
|
||||||
|
setUrl(`https://${input}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const startTest = async () => {
|
const startTest = async () => {
|
||||||
if (!url.trim()) {
|
if (!url.trim()) {
|
||||||
toast.error("Please enter a URL");
|
toast.error("Please enter a URL");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetUrl = url.trim();
|
const targetUrl = url.trim();
|
||||||
|
|
||||||
// If no protocol prefix, default to https://
|
|
||||||
if (!targetUrl.startsWith("http://") && !targetUrl.startsWith("https://")) {
|
|
||||||
targetUrl = `https://${targetUrl}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTesting(true);
|
setTesting(true);
|
||||||
setResult(null);
|
setResult(null);
|
||||||
@@ -218,6 +234,7 @@ const Tool: FC = () => {
|
|||||||
placeholder="e.g. https://example.com"
|
placeholder="e.g. https://example.com"
|
||||||
value={url}
|
value={url}
|
||||||
onChange={(e) => setUrl(e.target.value)}
|
onChange={(e) => setUrl(e.target.value)}
|
||||||
|
onBlur={handleUrlBlur}
|
||||||
onKeyPress={handleKeyPress}
|
onKeyPress={handleKeyPress}
|
||||||
disabled={testing}
|
disabled={testing}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -37,6 +37,46 @@ const Tool: FC = () => {
|
|||||||
const seqRef = useRef<number>(0);
|
const seqRef = useRef<number>(0);
|
||||||
const resultsContainerRef = useRef<HTMLDivElement>(null);
|
const resultsContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const handleHostBlur = () => {
|
||||||
|
if (!host.trim()) return;
|
||||||
|
|
||||||
|
let input = host.trim();
|
||||||
|
let cleanHost = input;
|
||||||
|
let extractedPort: string | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to parse as URL
|
||||||
|
const url = new URL(input.startsWith('http') ? input : `https://${input}`);
|
||||||
|
cleanHost = url.hostname;
|
||||||
|
|
||||||
|
// Extract port if specified in URL
|
||||||
|
if (url.port) {
|
||||||
|
extractedPort = url.port;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// If parsing fails, fallback to manual cleanup
|
||||||
|
const withoutProtocol = input.replace(/^https?:\/\//, "");
|
||||||
|
const withoutPath = withoutProtocol.split("/")[0];
|
||||||
|
|
||||||
|
// Check for port in the format hostname:port
|
||||||
|
const portMatch = withoutPath.match(/^(.+):(\d+)$/);
|
||||||
|
if (portMatch) {
|
||||||
|
cleanHost = portMatch[1];
|
||||||
|
extractedPort = portMatch[2];
|
||||||
|
} else {
|
||||||
|
cleanHost = withoutPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleanHost !== input) {
|
||||||
|
setHost(cleanHost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extractedPort) {
|
||||||
|
setPort(extractedPort);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const tcping = async () => {
|
const tcping = async () => {
|
||||||
if (!host.trim()) {
|
if (!host.trim()) {
|
||||||
toast.error("Please enter a hostname or IP");
|
toast.error("Please enter a hostname or IP");
|
||||||
@@ -45,14 +85,11 @@ const Tool: FC = () => {
|
|||||||
|
|
||||||
const seq = ++seqRef.current;
|
const seq = ++seqRef.current;
|
||||||
const portNum = parseInt(port) || 443;
|
const portNum = parseInt(port) || 443;
|
||||||
let targetUrl = host.trim();
|
const targetHost = host.trim();
|
||||||
|
|
||||||
// 移除协议前缀
|
// Build test URL
|
||||||
targetUrl = targetUrl.replace(/^https?:\/\//, "");
|
|
||||||
|
|
||||||
// 构建测试 URL
|
|
||||||
const protocol = portNum === 443 ? "https" : "http";
|
const protocol = portNum === 443 ? "https" : "http";
|
||||||
const url = `${protocol}://${targetUrl}:${portNum}`;
|
const url = `${protocol}://${targetHost}:${portNum}`;
|
||||||
|
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
|
|
||||||
@@ -182,6 +219,7 @@ const Tool: FC = () => {
|
|||||||
placeholder="e.g. example.com or 192.168.1.1"
|
placeholder="e.g. example.com or 192.168.1.1"
|
||||||
value={host}
|
value={host}
|
||||||
onChange={(e) => setHost(e.target.value)}
|
onChange={(e) => setHost(e.target.value)}
|
||||||
|
onBlur={handleHostBlur}
|
||||||
disabled={running}
|
disabled={running}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user