libcurl пропускает несколько байтов при загрузке файлов только с простого сервера Python и только в эмуляторе Android, работающем на Windows - PullRequest
0 голосов
/ 07 октября 2019

Сначала я скомпилировал libcurl на своем Mac с помощью следующего скрипта.

ARCH=$1
API_VER="21"

if [ $ARCH == "x86" ]; then
    HOST="i686"
    DEST_DIR="x86"
elif [ $ARCH == "x86_64" ]; then
    HOST="x86_64"
    DEST_DIR="x86_64"
elif [ $ARCH == "arm" ]; then
    HOST="arm"
    DEST_DIR="armeabi-v7a"
elif [ $ARCH == "arm64" ]; then
    HOST="aarch64"
    DEST_DIR="arm64-v8a"
fi

if [ $HOST == "arm" ]; then
    CLANG="armv7a-linux-androideabi$API_VER-clang"
    HOST="$HOST-linux-androideabi"
else
    CLANG="$HOST-linux-android$API_VER-clang"
    HOST="$HOST-linux-android"
fi

NDK_VER="20"
NDK_HOME="/Users/visor24-mac/Android-NDK/android-ndk-r$NDK_VER"
SYSROOT="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/sysroot"
INCPATH="/Users/visor24-mac/Project/External/prebuilt/include/android/${DEST_DIR}/openssl"
LIBPATH="/Users/visor24-mac/Project/External/prebuilt/lib/android/${DEST_DIR}"
PREFIX="/Users/visor24-mac/Project/External/curl/build/android/$ARCH"

export PATH="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin":"$PATH"
export CC="$CLANG"
export CPPFLAGS="-I${INCPATH}"
export CFLAGS="--sysroot ${SYSROOT} -O3"
export LDFLAGS="-L${LIBPATH} --sysroot ${SYSROOT}"

./configure --disable-shared --enable-static --host=$HOST --prefix=$PREFIX
make -j 4 && make install || exit 2

Затем коды для загрузки URL.

static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
    size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
    l_info << written;
    if ( size * nmemb != written )
        l_error;

    g_written += written;

    return written;
}

static void DownloadURL( const std::string& url, const std::string& fileName )
{
    CURL* curlHandle = nullptr;
    FILE* file = nullptr;

    curl_global_init(CURL_GLOBAL_ALL);
    curlHandle = curl_easy_init();
    auto rc = curl_easy_setopt( curlHandle, CURLOPT_URL, url.c_str() );
    rc = curl_easy_setopt( curlHandle, CURLOPT_VERBOSE, 0L );
    rc = curl_easy_setopt( curlHandle, CURLOPT_NOPROGRESS, 1L );
    rc = curl_easy_setopt( curlHandle, CURLOPT_SSL_VERIFYHOST, 0L );
    rc = curl_easy_setopt( curlHandle, CURLOPT_SSL_VERIFYPEER, 0L );
    rc = curl_easy_setopt( curlHandle, CURLOPT_WRITEFUNCTION, write_data );

    file = fopen( fileName.c_str(), "wb" );
    if ( file )
    {
        //curl_easy_setopt( curlHandle, CURLOPT_WRITEDATA, stdout );
        curl_easy_setopt( curlHandle, CURLOPT_WRITEDATA, file );
        rc = curl_easy_perform(curlHandle);
        if ( rc != CURLE_OK )
        {
            l_error << curl_easy_strerror( rc );
        }
        else
        {
            l_info << "CURL DOWNLOAD SUCCESS!!!!";
        }

        fclose( file );
    }

    curl_easy_cleanup( curlHandle );
    curl_global_cleanup();
}

И простой сервер Python.

python3 -m http.server

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

Передан частичный файл

Это происходит только в эмулятореработает на Windows и только при загрузке с моего простого сервера Python.

Реальное устройство телефона работает нормально. Эмулятор на Mac работает отлично. Даже эмулятор на Win работает нормально, когда я загружаю случайное веб-содержимое.

Я могу продолжать работать на своем Mac, и это устраняет эту проблему, но это немного раздражает, потому что Windows PC был моей основной машиной для разработки. И мне очень любопытно, что может вызвать это. Как я уже сказал, libcurl скомпилирован на Mac для всех ABI, затем я связал их с моим приложением в Android Studio на моем Win PC. Таким образом, даже если ABI одинаков как для libcurl, так и для моего приложения, кросс-компиляция ОС хоста не будет. Может ли это вызвать проблемы? Есть идеи?

...