mirror of
https://github.com/jason5ng32/MyIP.git
synced 2026-11-04 08:55:47 +00:00
Seven call sites hand-split trace bodies with the same lines.find +
split("=") pattern; extract utils/parse-trace.js and route them all
through it. The parser trims keys and values, so bodies re-serialized
with CRLF by middleboxes no longer leak a trailing "\r" into the IP.
SpeedTest's invalid-IP throw now carries a self-describing detail
(no-ip-line / empty-value / length + tail charcode) to tell response
tampering apart from format surprises.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
59 lines
2.0 KiB
JavaScript
59 lines
2.0 KiB
JavaScript
// Tests for frontend/utils/parse-trace.js — the shared /cdn-cgi/trace parser
|
|
// used by the getips/ sources, SpeedTest and RuleTest.
|
|
|
|
import assert from 'node:assert/strict';
|
|
import { describe, it } from 'node:test';
|
|
|
|
import { parseTrace } from '../frontend/utils/parse-trace.js';
|
|
|
|
// Shape of a real trace response (LF-joined below where a test needs it).
|
|
const TRACE_LINES = [
|
|
'fl=633f90',
|
|
'h=speed.cloudflare.com',
|
|
'ip=203.0.113.7',
|
|
'ts=1785340826.000',
|
|
'colo=SIN',
|
|
'loc=SG',
|
|
];
|
|
|
|
describe('parseTrace', () => {
|
|
it('parses a plain LF trace body into a key/value map', () => {
|
|
const out = parseTrace(TRACE_LINES.join('\n'));
|
|
assert.equal(out.ip, '203.0.113.7');
|
|
assert.equal(out.colo, 'SIN');
|
|
assert.equal(out.loc, 'SG');
|
|
});
|
|
|
|
it('tolerates CRLF line endings from rewriting middleboxes', () => {
|
|
// A TLS-decrypting proxy can re-serialize the body with \r\n; the
|
|
// trailing \r must not survive into the value (it would fail
|
|
// isValidIP downstream).
|
|
const out = parseTrace(TRACE_LINES.join('\r\n'));
|
|
assert.equal(out.ip, '203.0.113.7');
|
|
assert.equal(out.loc, 'SG');
|
|
});
|
|
|
|
it('splits on the first = only, keeping later ones in the value', () => {
|
|
const out = parseTrace('uag=Mozilla/5.0 (a=b; c=d)\nkex=X25519');
|
|
assert.equal(out.uag, 'Mozilla/5.0 (a=b; c=d)');
|
|
assert.equal(out.kex, 'X25519');
|
|
});
|
|
|
|
it('keeps an empty value distinct from an absent key', () => {
|
|
const out = parseTrace('ip=\ncolo=SIN');
|
|
assert.equal(out.ip, '');
|
|
assert.equal(out.loc, undefined);
|
|
});
|
|
|
|
it('skips blank lines and lines without a key', () => {
|
|
const out = parseTrace('\nip=1.2.3.4\n\n=orphan\nnokey\n');
|
|
assert.deepEqual(out, { ip: '1.2.3.4' });
|
|
});
|
|
|
|
it('returns an empty map for non-string input', () => {
|
|
assert.deepEqual(parseTrace(undefined), {});
|
|
assert.deepEqual(parseTrace(null), {});
|
|
assert.deepEqual(parseTrace(42), {});
|
|
});
|
|
});
|