| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- // Pure helpers for header-shape conversion between the panel's internal
- // HeaderEntry[] form and Xray's V2-style header map. Extracted from
- // XrayCommonClass.toHeaders / .toV2Headers so callers can stop relying on
- // the class hierarchy. Behavior is byte-equivalent to the legacy methods —
- // the shadow tests in src/test/headers.test.ts pin that.
- export interface HeaderEntry {
- name: string;
- value: string;
- }
- export type V2HeaderMap = Record<string, string | string[]>;
- // Expand a V2-style header map into the panel's flat HeaderEntry[]. A
- // header whose value is an array yields one entry per item, preserving
- // order; a string value yields a single entry. Non-object inputs (null,
- // undefined, primitives) yield [].
- export function toHeaders(v2Headers: unknown): HeaderEntry[] {
- const out: HeaderEntry[] = [];
- if (!v2Headers || typeof v2Headers !== 'object') return out;
- const map = v2Headers as Record<string, unknown>;
- for (const key of Object.keys(map)) {
- const values = map[key];
- if (typeof values === 'string') {
- out.push({ name: key, value: values });
- } else if (Array.isArray(values)) {
- for (const v of values) {
- if (typeof v === 'string') out.push({ name: key, value: v });
- }
- }
- }
- return out;
- }
- // Collapse a HeaderEntry[] back into a V2-style header map. When `arr` is
- // true (the default — matches Xray's TCP/WS/HTTP request/response shape),
- // duplicate header names accumulate into a string[]. When false (used for
- // WS/HTTPUpgrade/xHTTP top-level headers, sockopt portMap, etc.), the
- // last value wins. Entries with empty name or value are skipped — same as
- // the legacy ObjectUtil.isEmpty() filter.
- export function toV2Headers(headers: HeaderEntry[], arr: boolean = true): V2HeaderMap {
- const out: V2HeaderMap = {};
- for (const { name, value } of headers) {
- if (name == null || name === '' || value == null || value === '') continue;
- if (!(name in out)) {
- out[name] = arr ? [value] : value;
- continue;
- }
- const existing = out[name];
- if (arr && Array.isArray(existing)) {
- existing.push(value);
- } else {
- out[name] = value;
- }
- }
- return out;
- }
|