populateTransportSettings method
Populates Xray streamSettings from VLESS URL query parameters.
These settings feed both normal Xray configs and the iOS packet tunnel. The iOS provider later normalizes DNS/logging, but the transport shape created here is still the source of truth for TCP/Reality vs XHTTP tests.
Implementation
String populateTransportSettings({
required String transport,
required String? headerType,
required String? host,
required String? path,
required String? seed,
required String? quicSecurity,
required String? key,
required String? mode,
required String? serviceName,
String? extra,
}) {
String sni = '';
streamSettingsBuilder.network = transport;
if (transport == 'tcp') {
final tcpHeader = <String, dynamic>{"type": "none", "request": null};
final tcpSettings = <String, dynamic>{
"header": tcpHeader,
"acceptProxyProtocol": null
};
streamSettingsBuilder.tcpSettings = tcpSettings;
if (headerType == 'http') {
tcpHeader['type'] = 'http';
if (host != "" || path != "") {
final request = {
"path": path == null ? ["/"] : path.split(","),
"headers": {
"Host": host == null ? "" : host.split(","),
"User-Agent": [
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46",
],
"Accept-Encoding": [
"gzip, deflate",
],
"Connection": [
"keep-alive",
],
"Pragma": "no-cache",
},
"version": "1.1",
"method": "GET",
};
tcpHeader['request'] = request;
final headers = request['headers'] as Map<String, dynamic>;
final hosts = headers['Host'] as List;
sni = hosts.isNotEmpty ? hosts.first as String : sni;
}
} else {
tcpHeader['type'] = 'none';
sni = host != "" ? host ?? '' : '';
}
} else if (transport == 'kcp') {
streamSettingsBuilder.kcpSettings = {
"mtu": 1350,
"tti": 50,
"uplinkCapacity": 12,
"downlinkCapacity": 100,
"congestion": false,
"readBufferSize": 1,
"writeBufferSize": 1,
"header": {
"type": headerType ?? "none",
},
"seed": (seed == null || seed == '') ? null : seed,
};
} else if (transport == 'ws') {
final wsHeaders = {"Host": host ?? ""};
final wsSettings = {
"path": path ?? ['/'],
"headers": wsHeaders,
"maxEarlyData": null,
"useBrowserForwarding": null,
"acceptProxyProtocol": null,
};
streamSettingsBuilder.wsSettings = wsSettings;
sni = wsHeaders['Host'] as String;
} else if (transport == 'h2' || transport == 'http') {
streamSettingsBuilder.network = 'h2';
final h2Settings = {
"host": host?.split(",") ?? "",
"path": path ?? ['/'],
};
streamSettingsBuilder.h2Settings = h2Settings;
final hosts = h2Settings['host'];
sni = hosts is List && hosts.isNotEmpty ? hosts.first as String : sni;
} else if (transport == 'quic') {
streamSettingsBuilder.quicSettings = {
"security": quicSecurity ?? 'none',
"key": key ?? '',
"header": {"type": headerType ?? "none"},
};
} else if (transport == 'grpc') {
streamSettingsBuilder.grpcSettings = {
"serviceName": serviceName ?? "",
"multiMode": mode == "multi",
};
sni = host ?? "";
} else if (transport == 'xhttp') {
// XHTTP links often rely on server-specific knobs in `extra`. Preserving
// them is required for compatibility, but it is not proof the transport
// will work on iOS; the provider HTTP health check is the real signal.
streamSettingsBuilder.network = 'xhttp';
final xhttpExtra = decodeXhttpExtra(extra);
streamSettingsBuilder.xhttpSettings = {
"host": host ?? "",
"mode": mode ?? "auto",
"path": emptyToDefault(path, "/"),
if (xhttpExtra != null) "extra": xhttpExtra,
};
sni = host ?? "";
}
return sni;
}