Добавьте Outline SDK в свое мобильное приложение.

В этом документе описывается, как интегрировать Outline SDK в ваши мобильные приложения, уделяя особое внимание библиотеке MobileProxy для упрощенного управления локальным прокси-сервером.

MobileProxy — это библиотека на основе Go, разработанная для упрощения интеграции функций прокси в мобильные приложения. Она использует Go Mobile для создания мобильных библиотек, позволяя вам настраивать сетевые библиотеки вашего приложения для маршрутизации трафика через локальный прокси.

Приложение без MobileProxy

Контент-приложение без MobileProxy

Приложение с MobileProxy

Контент-приложение с MobileProxy

Шаг 1: Создание мобильных библиотек MobileProxy

Используйте gomobile для компиляции кода Go в библиотеки для Android и iOS.

  1. Клонируйте репозиторий Outline SDK:

    git clone https://github.com/Jigsaw-Code/outline-sdk.git
    cd outline-sdk/x
    
  2. Соберите двоичные файлы Go Mobile с помощью go build :

    go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
    

    Добавление поддержки Psiphon

    Вы можете добавить поддержку использования сети Psiphon , выполнив следующие дополнительные шаги:

    • Обратитесь к команде Psiphon, чтобы получить конфигурацию, которая даст вам доступ к их сети. Для этого может потребоваться контракт.
    • Добавьте полученную конфигурацию Psiphon в fallback раздел конфигурации SmartDialer .
    • Создайте мобильный прокси, используя флаг -tags psiphon :

      go build -tags psiphon -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
      

    Флаг -tags psiphon необходим, поскольку кодовая база Psiphon лицензирована по GPL, что может налагать лицензионные ограничения на ваш собственный код. Вы можете рассмотреть возможность получения от них специальной лицензии.

  3. Создайте мобильные библиотеки и добавьте их в свой проект:

    андроид

    PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=android -androidapi=21 -o "$(pwd)/out/mobileproxy.aar" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy
    

    В Android Studio выберите Файл > Импорт проекта… , чтобы импортировать сгенерированный пакет out/mobileproxy.aar . Для получения дополнительной информации см. Сборка и развертывание на Android от Go Mobile.

    iOS

    PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=ios -iosversion=11.0 -o "out/mobileproxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy
    

    Перетащите пакет out/mobileproxy.xcframework в проект Xcode. Для получения дополнительной информации см. Сборка и развертывание на iOS от Go Mobile.

Шаг 2: Запустите MobileProxy

Инициализируйте и запустите локальный прокси MobileProxy в среде выполнения вашего приложения. Вы можете использовать либо статическую конфигурацию транспорта, либо Smart Proxy для динамического выбора стратегии.

  • Статическая конфигурация транспорта : используйте функцию RunProxy с локальным адресом и конфигурацией транспорта.

    андроид

    import mobileproxy.*
    
    val dialer = StreamDialer("split:3")
    
    // Use port zero to let the system pick an open port for you.
    val proxy = Mobileproxy.runProxy("localhost:0", dialer)
    // Configure your networking library using proxy.host() and proxy.port() or proxy.address().
    // ...
    // Stop running the proxy.
    proxy.stop()
    

    iOS

    import Mobileproxy
    
    let dialer = MobileproxyStreamDialer("split:3")
    
    // Use port zero to let the system pick an open port for you.
    let proxy = MobileproxyRunProxy("localhost:0", dialer)
    // Configure your networking library using proxy.host() and proxy.port() or proxy.address().
    // ...
    // Stop running the proxy.
    proxy.stop()
    
  • Smart Proxy : Smart Proxy динамически выбирает стратегии DNS и TLS на основе указанных тестовых доменов. Вам необходимо указать стратегию конфигурации в формате YAML ( пример ).

    андроид

    val testDomains = Mobileproxy.newListFromLines("www.youtube.com\ni.ytimg.com")
    val strategiesConfig = "..."  // Config YAML.
    val dialer = Mobileproxy.newSmartStreamDialer(testDomains, strategiesConfig, Mobileproxy.newStderrLogWriter())
    
    // Use port zero to let the system pick an open port for you.
    val proxy = Mobileproxy.runProxy("localhost:0", dialer)
    // Configure your networking library using proxy.host() and proxy.port() or proxy.address().
    // ...
    // Stop running the proxy.
    proxy.stop()
    

    iOS

    import Mobileproxy
    
    var dialerError: NSError?
    let testDomains = MobileproxyNewListFromLines("www.youtube.com\ni.ytimg.com")
    let strategiesConfig = "..."  // Config YAML.
    let dialer = MobileproxyNewSmartStreamDialer(
        testDomains,
        strategiesConfig,
        MobileproxyNewStderrLogWriter(),
        &dialerError
    )
    
    var proxyError: NSError?
    // Use port zero to let the system pick an open port for you.
    MobileproxyRunProxy("localhost:0", dialer, &proxyError)
    // Configure your networking library using proxy.host() and proxy.port() or proxy.address().
    // ...
    // Stop running the proxy.
    proxy.stop()
    

Шаг 3: Настройка HTTP-клиентов и сетевых библиотек

Настройте сетевые библиотеки на использование адреса и порта локального прокси-сервера.

Http-клиент Dart/Flutter

Установите прокси с помощью HttpClient.findProxy .

HttpClient client = HttpClient();
client.findProxy = (Uri uri) {
  return "PROXY " + proxy.address();
};

OkHttp (Android)

Установите прокси с помощью OkHttpClient.Builder.proxy .

val proxyConfig = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxy.host(), proxy.port()))
val client = OkHttpClient.Builder().proxy(proxyConfig).build()

JVM (Java, Kotlin)

Настройте прокси-сервер для использования с системными свойствами :

System.setProperty("http.proxyHost", proxy.host())
System.setProperty("http.proxyPort", String.valueOf(proxy.port()))
System.setProperty("https.proxyHost", proxy.host())
System.setProperty("https.proxyPort", String.valueOf(proxy.port()))

Android-просмотр веб-страниц

Примените конфигурацию прокси ко всем веб-представлениям в вашем приложении с помощью библиотеки androidx.webview :

ProxyController.getInstance()
    .setProxyOverride(
        ProxyConfig.Builder()
            .addProxyRule(this.proxy!!.address())
            .build(),
        {}, // execution context for the following callback - do anything needed here once the proxy is applied, like refreshing web views
        {} // callback to be called once the ProxyConfig is applied
    )

Веб-просмотр iOS

Начиная с iOS 17, вы можете добавить конфигурацию прокси в WKWebView , используя его свойство WKWebsiteDataStore :

let configuration = WKWebViewConfiguration()
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(proxyHost), port: NWEndpoint.Port(proxyPort)!)
let proxyConfig = ProxyConfiguration.init(httpCONNECTProxy: endpoint)
let websiteDataStore = WKWebsiteDataStore.default()
websiteDataStore.proxyConfigurations = [proxyConfig]
let webview = WKWebView(configuration: configuration)

Дополнительно: создание собственной мобильной библиотеки

Для расширенных вариантов использования вы можете создавать собственные мобильные библиотеки:

  1. Создайте библиотеку Go : разработайте пакет Go, включающий необходимые функции SDK.
  2. Генерация мобильных библиотек : использование gomobile bind для создания архивов Android (AAR) и фреймворков Apple. Примеры:
  3. Интеграция в ваше приложение : добавьте созданную библиотеку в ваше мобильное приложение.