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