From e992b8ddfde05b872b0457d5542cb759b6176925 Mon Sep 17 00:00:00 2001 From: John Holdsworth Date: Fri, 13 Oct 2017 17:58:46 +0100 Subject: [PATCH] For HTTPS on Android III --- Foundation/URLSession/http/EasyHandle.swift | 42 ++++++----------- android/README.md | 51 --------------------- android/builder.sh | 21 --------- android/install.sh | 21 --------- android/package.sh | 22 --------- android/prepare.sh | 17 ------- android/updater.sh | 40 ---------------- 7 files changed, 13 insertions(+), 201 deletions(-) delete mode 100644 android/README.md delete mode 100755 android/builder.sh delete mode 100755 android/install.sh delete mode 100755 android/package.sh delete mode 100755 android/prepare.sh delete mode 100755 android/updater.sh diff --git a/Foundation/URLSession/http/EasyHandle.swift b/Foundation/URLSession/http/EasyHandle.swift index ea0356d9d7..5ec3ec1cab 100644 --- a/Foundation/URLSession/http/EasyHandle.swift +++ b/Foundation/URLSession/http/EasyHandle.swift @@ -56,9 +56,6 @@ internal final class _EasyHandle { fileprivate var headerList: _CurlStringList? fileprivate var pauseState: _PauseState = [] internal var timeoutTimer: _TimeoutSource! - #if os(Android) - static fileprivate var _CAInfoFile: UnsafeMutablePointer? - #endif init(delegate: _EasyHandleDelegate) { self.delegate = delegate @@ -170,20 +167,20 @@ extension _EasyHandle { let protocols = (CFURLSessionProtocolHTTP | CFURLSessionProtocolHTTPS) try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionPROTOCOLS, protocols).asError() try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionREDIR_PROTOCOLS, protocols).asError() - #if os(Android) - // See https://curl.haxx.se/docs/sslcerts.html - // For SSL to work you need "cacert.pem" to be accessable - // at the path pointed to by the URLSessionCAInfo env var. - // Downloadable here: https://curl.haxx.se/ca/cacert.pem - if let caInfo = _EasyHandle._CAInfoFile { - if String(cString: caInfo) == "UNSAFE_SSL_NOVERIFY" { - try! CFURLSession_easy_setopt_int(rawHandle, CFURLSessionOptionSSL_VERIFYPEER, 0).asError() - } - else { - try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, caInfo).asError() - } +#if os(Android) + // See https://curl.haxx.se/docs/sslcerts.html + // For SSL on Android you need a "cacert.pem" to be + // accessible at the path pointed to by this env var. + // Downloadable here: https://curl.haxx.se/ca/cacert.pem + if let caInfo = getenv("URLSessionCertificateAuthorityInfoFile") { + if String(cString: caInfo) == "INSECURE_SSL_NO_VERIFY" { + try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionSSL_VERIFYPEER, 0).asError() + } + else { + try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, caInfo).asError() } - #endif + } +#endif //TODO: Added in libcurl 7.45.0 //TODO: Set default protocol for schemeless URLs //CURLOPT_DEFAULT_PROTOCOL available only in libcurl 7.45.0 @@ -630,19 +627,6 @@ extension _EasyHandle._CurlStringList { } } -#if os(Android) -extension URLSession { - - public static func setCAInfoFile(_ _CAInfoFile: String) { - free(_EasyHandle._CAInfoFile) - _CAInfoFile.withCString { - _EasyHandle._CAInfoFile = strdup($0) - } - } - -} -#endif - extension CFURLSessionEasyCode : Equatable { public static func ==(lhs: CFURLSessionEasyCode, rhs: CFURLSessionEasyCode) -> Bool { return lhs.value == rhs.value diff --git a/android/README.md b/android/README.md deleted file mode 100644 index ef274b1b07..0000000000 --- a/android/README.md +++ /dev/null @@ -1,51 +0,0 @@ - -## Android Port of Foundation module - -This directory contains scripts used in the port of Foundation to -an Android toolchain. The short version of the story is that after -downloading the swift sources use the script "prepare.sh" in this -directory to install prebuilt binaries and headers for libxml, -libcurl and libdispatch then run the script "builder.sh". - -This build requires the path to a [r12 Android NDK](http://developer.android.com/ndk/downloads/index.html) in the -`ANDROID_NDK_HOME` environment variable and the path to the -android port of the "icu" libraries in `ANDROID_ICU_UC` -downloaded from [here](https://github.com/SwiftAndroid/libiconv-libicu-android/releases/download/android-ndk-r12/libiconv-libicu-armeabi-v7a-ubuntu-15.10-ndk-r12.tar.gz). -The port was tested against api 21 on a Android v5.1.1 LG K4 Phone (Lollipop) -and requires an Ubuntu 15 host with the Android NDK Gold linker from -`toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin` installed as /usr/bin/ld.gold. - -The pre-built binaries were built from the following repos: - -[https://github.com/curl/curl](https://github.com/curl/curl) - -[https://github.com/android/platform_external_libxml2](https://github.com/android/platform_external_libxml2) - -[https://github.com/apple/swift-corelibs-libdispatch](https://github.com/apple/swift-corelibs-libdispatch) - -[https://github.com/mheily/libpwq](https://github.com/mheily/libpwq) - -[https://github.com/mheily/libkqueue](https://github.com/mheily/libkqueue) - -To build these the recipe was generally the same. autogen or configure -for Linux then alter their Makefiles to have CFLAGS = include: --target=armv7-none-linux-androideabi --sysroot=$(ANDROID_NDK_HOME)/platforms/android-21/arch-arm. - -There is a known issue when libdispatch background tasks exit -they will cause an exception as DetachCurrentThread has not -been called. To avoid this your app must include the line: - - DispatchGroup.threadCleanupCallback = JNI_DetachCurrentThread - -JNI_DetachCurrentThread is available in the package java_swift -available here: https://github.com/SwiftJava/java_swift - -Pre-built binaries of an Swift compiler with support for Android -including Foundation available here: - -http://johnholdsworth.com/android_toolchain.tgz - -### Other resources - -Check out the [SwiftAndroid](https://github.com/SwiftAndroid) and -[SwiftJava](https://github.com/SwiftJava) github projects for -starter Android applications and resources. diff --git a/android/builder.sh b/android/builder.sh deleted file mode 100755 index d00b8dad50..0000000000 --- a/android/builder.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -x -# -# Build Android toolchain including Foundation -# - -cd "$(dirname $0)" && -#./prepare.sh && -./install.sh -u && - -pushd "../../swift" && -./utils/build-script \ - -R --skip-build-libdispatch --foundation \ - --android \ - --android-ndk "${ANDROID_NDK_HOME:?Please set ANDROID_NDK_HOME to path to an Android NDK downloaded from http://developer.android.com/ndk/downloads/index.html}" \ - --android-api-level 21 \ - --android-icu-uc "${ANDROID_ICU_UC:?Please set ANDROID_ICU_UC to path to Android ICU downloaded from https://github.com/SwiftAndroid/libiconv-libicu-android/releases/download/android-ndk-r12/libiconv-libicu-armeabi-v7a-ubuntu-15.10-ndk-r12.tar.gz}/armeabi-v7a" \ - --android-icu-uc-include "${ANDROID_ICU_UC}/armeabi-v7a/icu/source/common" \ - --android-icu-i18n "${ANDROID_ICU_UC}/armeabi-v7a" \ - --android-icu-i18n-include "${ANDROID_ICU_UC}/armeabi-v7a/icu/source/i18n" && - -popd && ./install.sh diff --git a/android/install.sh b/android/install.sh deleted file mode 100755 index c724695771..0000000000 --- a/android/install.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# Simple script to move Android Foundation into toolchain -# To build it again after this, use install.sh -u to reset -# - -cd "$(dirname $0)" - -SWIFT_ROOT="$(dirname $(dirname $(which swiftc)))" -BUILD_DIR="$(dirname $SWIFT_ROOT)" - -if [[ "$1" == "-u" ]]; then - rm -rf "${SWIFT_ROOT}/lib/swift/CoreFoundation" - exit -fi - -\cp -v "${BUILD_DIR}/foundation-linux-x86_64/Foundation/libFoundation.so" "${SWIFT_ROOT}/lib/swift/android" && - -\cp -v "${BUILD_DIR}/foundation-linux-x86_64/Foundation/Foundation.swift"* "${SWIFT_ROOT}/lib/swift/android/armv7" && - -rsync -arv "${BUILD_DIR}/foundation-linux-x86_64/Foundation/usr/lib/swift/CoreFoundation" "${SWIFT_ROOT}/lib/swift/" diff --git a/android/package.sh b/android/package.sh deleted file mode 100755 index 4657c49ca1..0000000000 --- a/android/package.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# -# Prepare binary package used to build Foundation for Android -# - -cd "$(dirname $0)" && -TAR_FILE="$(pwd)/android_dispatch" && - -cd "../../platform_external_libxml2/include" && -tar cf "$TAR_FILE.tar" libxml && - -cd "../../curl/include" && -tar rf "$TAR_FILE.tar" curl && - -cd "$(dirname $(dirname $(which swiftc)))/lib/swift" && - -tar rf "$TAR_FILE.tar" dispatch android/lib{xml2,curl,dispatch}.so android/armv7/Dispatch.swift* && - -gzip "$TAR_FILE.tar" && -\mv "$TAR_FILE.tar.gz" "$TAR_FILE.tgz" && - -tar tfvz "$TAR_FILE.tgz" diff --git a/android/prepare.sh b/android/prepare.sh deleted file mode 100755 index 5e3ce2d7d2..0000000000 --- a/android/prepare.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# Prepare swift sourcerelease to build Foundation for Android -# - -BUILD_DIR="build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift" - -cd "$(dirname $0)" && -TAR_FILE="$(pwd)/android_dispatch.tgz" && - -if [[ ! -f "${TAR_FILE}" ]]; then - echo "Fetching binaries and headers for libxml2, libcurl and libdispatch" - curl "https://raw.githubusercontent.com/SwiftJava/SwiftJava/master/android_dispatch.tgz" > "${TAR_FILE}" -fi - -cd "../.." && mkdir -p "${BUILD_DIR}" && -cd "${BUILD_DIR}" && tar xfvz "${TAR_FILE}" diff --git a/android/updater.sh b/android/updater.sh deleted file mode 100755 index 1dcd2c7107..0000000000 --- a/android/updater.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# -# Move freshly built dependencies for Foundation into -# build directory to be available for it's compilation. -# -# libxml2.so built from the android platform port: -# https://github.com/android/platform_external_libxml2 -# -# This is the most useful page found but it's not complete -# http://stackoverflow.com/questions/12052089/using-libxml-for-android -# Don't set CFLAGS or LDFLAGS and use ./autogen.sh instead of "configure" -# Remove HTMLparser.lo and HTMLtree.lo from the Makefile and make sure -# LIBXML_HTML_ENABLED and LIBXML_ICONV_ENABLED were not enabled in file -# "include/libxml/xmlversion.h". Add the following to CFLAGS in Makefile: -# -nostdlib --target=armv7-none-linux-androideabi -# --sysroot=$ANDROID_NDK/platforms/android-21/arch-arm -# -# libcurl.so is built similarly from https://github.com/curl/curl -# -# libdispatch.so is a difficult build soon to be automated by another PR. -# - -ANDROID_ICU_UC="${ANDROID_ICU_UC:-$HOME/libiconv-libicu-android}" - -cd "$(dirname $0)" && - -SWIFT_ROOT="$(dirname $(dirname $(which swiftc)))" && -BUILD_DIR="$(dirname $SWIFT_ROOT)" && - -\cp -v ../../platform_external_libxml2/libxml2.so ../../curl/libcurl.so ../../swift-corelibs-libdispatch/libdispatch.so "$ANDROID_ICU_UC"/armeabi-v7a/libicu*.so "${SWIFT_ROOT}/lib/swift/android" && - -\cp -v "${BUILD_DIR}/libdispatch-linux-x86_64/src/swift/Dispatch.swift"* "${SWIFT_ROOT}/lib/swift/android/armv7" && - -rsync -arv "../../swift-corelibs-libdispatch/dispatch" "${SWIFT_ROOT}/lib/swift/" && - -\cp -v "../../swift-corelibs-libdispatch/private/"*.h "${SWIFT_ROOT}/lib/swift/dispatch" && - -rpl -R -e libicu libscu "${SWIFT_ROOT}/lib/swift/android"/lib{icu,swift,Foundation,xml2}*.so && - -for i in "${SWIFT_ROOT}/lib/swift/android"/libicu*.so; do \mv -f $i ${i/libicu/libscu}; done