How to make https requests from an Objective-C++ iOS app using xCode?

131 Views Asked by At

Here is my problem, I want to make an iOS app that will make https (not just http) requests using Objective-C++ (I mainly code in C++ with SDL) but I can't figure out how to do it. I simply want to retrieve the html code from https websites to use them in my app.

Can someone explain to me how I can achieve that? Or at least tell me what I did wrong in my attempt.

In my attempt, I found yhirose's header-only and cross-platform library cpp-httplib and it works like a charm when I make simple http requests.

Now like I said I want to make https requests as well but that's where it gets difficult as it requires OpenSSL.

First, I defined CPPHTTPLIB_OPENSSL_SUPPORT before including httplib.h so it uses openssl:

#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"

From there, openssl/err.h, openssl/evp.h, openssl/ssl.h and openssl/x509v3.h were missing, so I added krzyzanowskim's OpenSSL v1.1.2100 as a Package Dependencie in my xCode project using the Swift Package Manager as instructed on their github repository:

dependencies: [
    .package(url: "https://github.com/krzyzanowskim/OpenSSL.git", .upToNextMinor(from: "1.1.1700"))
]

Now the application compiles just fine but when I try to make an https request, the httplib::Result cannot be used and I get a runtime error Thread 1: EXC_BAD_ACCESS (code=1, address=0x18) when trying to access either its body or its status:

// HTTPS
httplib::Client cli("https://stackoverflow.com");
httplib::Result res = cli.Get("/questions");
    
std::cout << "--------------- RESULT ---------------" << std::endl;
std::cout << res << std::endl;
std::cout << "--------------- ERRORS ---------------" << std::endl;
std::cout << res.error() << std::endl;
std::cout << "--------------- STATUS ---------------" << std::endl;
std::cout << res->status << std::endl;
std::cout << "---------------- BODY ----------------" << std::endl;
std::cout << res->body << std::endl;
std::cout << "--------------------------------------" << std::endl;

OUTPUT (Note the SSL server verification failed error):

--------------- RESULT ---------------
0
--------------- ERRORS ---------------
SSL server verification failed (10)
--------------- STATUS ---------------
(lldb)   <-- [Thread 1: EXC_BAD_ACCESS (code=1, address=0x18)]

Note that regular http requests still work (though I get 301 Moved Permanently from most websites which is normal):

// HTTP
httplib::Client cli("http://stackoverflow.com");
httplib::Result res = cli.Get("/questions");
    
std::cout << "--------------- RESULT ---------------" << std::endl;
std::cout << res << std::endl;
std::cout << "--------------- ERRORS ---------------" << std::endl;
std::cout << res.error() << std::endl;
std::cout << "--------------- STATUS ---------------" << std::endl;
std::cout << res->status << std::endl;
std::cout << "---------------- BODY ----------------" << std::endl;
std::cout << res->body << std::endl;
std::cout << "--------------------------------------" << std::endl;

OUTPUT:

--------------- RESULT ---------------
1
--------------- ERRORS ---------------
Success (no error) (0)
--------------- STATUS ---------------
301
---------------- BODY ----------------

--------------------------------------

I imagined that something was wrong with my OpenSSL package (maybe since it's a swift package?), so I put that theory to test by making a simple hashing method and it worked as expected, so I concluded it was fine:

#include <iostream>
#include <openssl/sha.h>

std::string hashWithSha256(std::string input)
{
    std::string output = "";
    unsigned char buffer[32];
    
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, input.c_str(), input.size());
    SHA256_Final(buffer, &sha256);
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
        output += buffer[i];
    return output;
}

int main( int argc, char* args[] )
{
    std::string input = "Hello World!";
    std::string output = hashWithSha256(input);

    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
        printf("%02hhX", output[i]);

    return 0;
}

OUTPUT (Result is correct, see):

7F83B1657FF1FC53B92DC18148A1D65DFC2D4B1FA3D677284ADDD200126D9069

Am I missing something obvious? I don't understand why cpp-httplib won't work while OpenSSL seems to be working as expected...

0

There are 0 best solutions below