(req)
| 5562 | } |
| 5563 | |
| 5564 | async function handleCheckProxyRequest(req) { |
| 5565 | if (req.method === 'OPTIONS') { |
| 5566 | return new Response(null, { |
| 5567 | status: 204, |
| 5568 | headers: CHECK_RESPONSE_HEADERS, |
| 5569 | }); |
| 5570 | } |
| 5571 | |
| 5572 | if (req.method !== 'GET' && req.method !== 'POST') { |
| 5573 | return checkJsonResponse( |
| 5574 | { success: false, error: 'method not allowed', usage: USAGE_EXAMPLES }, |
| 5575 | 405 |
| 5576 | ); |
| 5577 | } |
| 5578 | |
| 5579 | try { |
| 5580 | const url = new URL(req.url); |
| 5581 | const pathname = url.pathname.replace(/\/+$/, '') || '/'; |
| 5582 | if (pathname !== '/check') { |
| 5583 | return checkJsonResponse( |
| 5584 | { success: false, error: 'not found', usage: USAGE_EXAMPLES }, |
| 5585 | 404 |
| 5586 | ); |
| 5587 | } |
| 5588 | |
| 5589 | const { searchParams } = url; |
| 5590 | const bodyText = req.method === 'POST' ? await req.text() : ''; |
| 5591 | const body = bodyText ? JSON.parse(bodyText) : {}; |
| 5592 | |
| 5593 | const rawCandidates = body.proxyips ?? body.proxyip ?? searchParams.get('proxyip'); |
| 5594 | |
| 5595 | const rawList = Array.isArray(rawCandidates) ? rawCandidates : `${rawCandidates ?? ''}`.split(/[\s,]+/); |
| 5596 | const candidates = [...new Set(rawList.map((item) => `${item ?? ''}`.trim()).filter(Boolean))]; |
| 5597 | const timeoutMs = parsePositiveInt(body.timeoutMs ?? searchParams.get('timeoutMs'), DEFAULT_TIMEOUT_MS); |
| 5598 | const readLimit = parsePositiveInt(body.readLimit ?? searchParams.get('readLimit'), DEFAULT_READ_LIMIT); |
| 5599 | |
| 5600 | if (!candidates.length) { |
| 5601 | return checkJsonResponse( |
| 5602 | { success: false, error: 'missing proxyip', usage: USAGE_EXAMPLES }, |
| 5603 | 400 |
| 5604 | ); |
| 5605 | } |
| 5606 | |
| 5607 | const results = await Promise.all( |
| 5608 | candidates.map(async (rawCandidate) => { |
| 5609 | const defaultPort = 443; |
| 5610 | let candidate; |
| 5611 | if (rawCandidate.startsWith('[')) { |
| 5612 | const match = rawCandidate.match(/^\[([^\]]+)\](?::(\d+))?$/); |
| 5613 | if (!match) throw new Error(`invalid IPv6 candidate: ${rawCandidate}`); |
| 5614 | candidate = { raw: rawCandidate, hostname: match[1], port: Number(match[2]) || defaultPort }; |
| 5615 | } else { |
| 5616 | const [, hostname = rawCandidate, port] = rawCandidate.match(/^([^:]+):(\d+)$/) ?? []; |
| 5617 | candidate = { raw: rawCandidate, hostname, port: Number(port) || defaultPort }; |
| 5618 | } |
| 5619 | |
| 5620 | const probeResults = await Promise.all( |
| 5621 | PROBE_TARGETS.map(async (target) => { |
no test coverage detected