summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Leege <bleege@gmail.com>2015-09-23 09:49:53 -0500
committerBrad Leege <bleege@gmail.com>2015-09-23 09:49:53 -0500
commit888444cc41aeb2a19c25a4202aa4adc14e5dc026 (patch)
tree64250abf948d51bbcbcf7ffbc9cd7017c1c45b44
parent8cf927f6c423ad5e5ce9c8931002ee1c1dce1d9d (diff)
parent4e885d600a4776d087c8c0e94719df9e45293408 (diff)
downloadqtlocation-mapboxgl-888444cc41aeb2a19c25a4202aa4adc14e5dc026.tar.gz
Merge branch 'android-curl'
-rw-r--r--android/mapboxgl-app.gypi5
-rw-r--r--platform/default/http_request_curl.cpp109
-rw-r--r--scripts/android/configure.sh2
-rw-r--r--scripts/android/defaults.mk2
4 files changed, 117 insertions, 1 deletions
diff --git a/android/mapboxgl-app.gypi b/android/mapboxgl-app.gypi
index 5731d21f85..7a8c52d5b6 100644
--- a/android/mapboxgl-app.gypi
+++ b/android/mapboxgl-app.gypi
@@ -25,6 +25,8 @@
'<@(boost_cflags)',
],
'libraries': [
+ '<@(openssl_static_libs)',
+ '<@(libcurl_static_libs)',
'<@(libpng_static_libs)',
'<@(jpeg_static_libs)',
'<@(sqlite_static_libs)',
@@ -43,6 +45,8 @@
'<@(libpng_ldflags)',
'<@(jpeg_ldflags)',
'<@(sqlite_ldflags)',
+ '<@(openssl_ldflags)',
+ '<@(libcurl_ldflags)',
'<@(zlib_ldflags)',
'<@(libzip_ldflags)',
],
@@ -70,6 +74,7 @@
'copies': [
{
'files': [
+ '../common/ca-bundle.crt',
'../styles/styles'
],
'destination': '<(pwd)/../android/java/MapboxGLAndroidSDK/src/main/assets'
diff --git a/platform/default/http_request_curl.cpp b/platform/default/http_request_curl.cpp
index e416034b40..0f7f8c0ac5 100644
--- a/platform/default/http_request_curl.cpp
+++ b/platform/default/http_request_curl.cpp
@@ -11,6 +11,12 @@
#include <curl/curl.h>
+#ifdef __ANDROID__
+#include <mbgl/android/jni.hpp>
+#include <zip.h>
+#include <openssl/ssl.h>
+#endif
+
#include <queue>
#include <map>
#include <cassert>
@@ -325,6 +331,104 @@ int HTTPCURLContext::startTimeout(CURLM * /* multi */, long timeout_ms, void *us
// -------------------------------------------------------------------------------------------------
+#ifdef __ANDROID__
+
+// This function is called to load the CA bundle
+// from http://curl.haxx.se/libcurl/c/cacertinmem.html¯
+static CURLcode sslctx_function(CURL * /* curl */, void *sslctx, void * /* parm */) {
+
+ int error = 0;
+ struct zip *apk = zip_open(mbgl::android::apkPath.c_str(), 0, &error);
+ if (apk == nullptr) {
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ struct zip_file *apkFile = zip_fopen(apk, "assets/ca-bundle.crt", ZIP_FL_NOCASE);
+ if (apkFile == nullptr) {
+ zip_close(apk);
+ apk = nullptr;
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ struct zip_stat stat;
+ if (zip_stat(apk, "assets/ca-bundle.crt", ZIP_FL_NOCASE, &stat) != 0) {
+ zip_fclose(apkFile);
+ apkFile = nullptr;
+ zip_close(apk);
+ apk = nullptr;
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ if (stat.size > std::numeric_limits<int>::max()) {
+ zip_fclose(apkFile);
+ apkFile = nullptr;
+ zip_close(apk);
+ apk = nullptr;
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ const auto pem = std::make_unique<char[]>(stat.size);
+
+ if (static_cast<zip_uint64_t>(zip_fread(apkFile, reinterpret_cast<void *>(pem.get()), stat.size)) != stat.size) {
+ zip_fclose(apkFile);
+ apkFile = nullptr;
+ zip_close(apk);
+ apk = nullptr;
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ // get a pointer to the X509 certificate store (which may be empty!)
+ X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
+ if (store == nullptr) {
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ // get a BIO
+ BIO *bio = BIO_new_mem_buf(pem.get(), static_cast<int>(stat.size));
+ if (bio == nullptr) {
+ store = nullptr;
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ // use it to read the PEM formatted certificate from memory into an X509
+ // structure that SSL can use
+ X509 *cert = nullptr;
+ while (PEM_read_bio_X509(bio, &cert, 0, nullptr) != nullptr) {
+ if (cert == nullptr) {
+ BIO_free(bio);
+ bio = nullptr;
+ store = nullptr;
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ // add our certificate to this store
+ if (X509_STORE_add_cert(store, cert) == 0) {
+ X509_free(cert);
+ cert = nullptr;
+ BIO_free(bio);
+ bio = nullptr;
+ store = nullptr;
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+
+ X509_free(cert);
+ cert = nullptr;
+ }
+
+ // decrease reference counts
+ BIO_free(bio);
+ bio = nullptr;
+
+ zip_fclose(apkFile);
+ apkFile = nullptr;
+ zip_close(apk);
+ apk = nullptr;
+
+ // all set to go
+ return CURLE_OK;
+}
+#endif
+
HTTPCURLRequest::HTTPCURLRequest(HTTPCURLContext* context_, const Resource& resource_, Callback callback_, uv_loop_t*, std::shared_ptr<const Response> response_)
: HTTPRequestBase(resource_, callback_),
context(context_),
@@ -354,7 +458,12 @@ HTTPCURLRequest::HTTPCURLRequest(HTTPCURLContext* context_, const Resource& reso
handleError(curl_easy_setopt(handle, CURLOPT_PRIVATE, this));
handleError(curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, error));
+#ifdef __ANDROID__
+ handleError(curl_easy_setopt(handle, CURLOPT_SSLCERTTYPE, "PEM"));
+ handleError(curl_easy_setopt(handle, CURLOPT_SSL_CTX_FUNCTION, sslctx_function));
+#else
handleError(curl_easy_setopt(handle, CURLOPT_CAINFO, "ca-bundle.crt"));
+#endif
handleError(curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1));
handleError(curl_easy_setopt(handle, CURLOPT_URL, resource.url.c_str()));
handleError(curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writeCallback));
diff --git a/scripts/android/configure.sh b/scripts/android/configure.sh
index 70c8973a8b..5e5a9034c1 100644
--- a/scripts/android/configure.sh
+++ b/scripts/android/configure.sh
@@ -1,6 +1,8 @@
#!/usr/bin/env bash
BOOST_VERSION=1.57.0
+LIBCURL_VERSION=7.40.0
+OPENSSL_VERSION=1.0.1l
LIBPNG_VERSION=1.6.16
JPEG_VERSION=v9a
SQLITE_VERSION=3.8.8.1
diff --git a/scripts/android/defaults.mk b/scripts/android/defaults.mk
index 29f047c887..436f9db710 100644
--- a/scripts/android/defaults.mk
+++ b/scripts/android/defaults.mk
@@ -1,7 +1,7 @@
HEADLESS ?= none
PLATFORM ?= android
ASSET ?= zip
-HTTP ?= android
+HTTP ?= curl
CACHE ?= sqlite
GYP_FLAVOR_SUFFIX=-android