populateTransportSettings method

String populateTransportSettings({
  1. required String transport,
  2. required String? headerType,
  3. required String? host,
  4. required String? path,
  5. required String? seed,
  6. required String? quicSecurity,
  7. required String? key,
  8. required String? mode,
  9. required String? serviceName,
  10. String? extra,
})

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;
}