Libcurl Ssl Error After Fork()

libCurl SSL error after fork()

To make this work, you need to call curl_global_cleanup before fork and curl_global_init again after fork. Someone in the libcurl mailing list mentioned that this is a common problem when calling fork after initializing libraries that need to be initialized.

Curl and pcntl_fork()

After a lot of research, I uncovered that the issue is not a new and is a problem with php's implementation of CURL. These other questions helped me to come up with the solution I've shared below:

  • SSL Requests made with cURL fail after process fork
  • libCurl SSL error after fork()

What I ended up doing was to use pcntl_exec which replaces the current child process with the command provided.

$this->initialize_curl();
$this->connect_database();

// prime the queue
$this->add_url_to_queue($this->source_url, 0, 0);
$this->process_next_url_in_queue($this->get_next_url_in_queue());

// loop until we have processed all URL's
while (1) {
$url = $this->get_next_url_in_queue();

// disconnect from the database before forking since we don't want to
// share the database connection with child processes - the first one
// will close it and ruin the fun for the other children.
curl_close($this->ch);
$this->db->close();

// create child
$pid = pcntl_fork();

// handle forked processing
switch ($pid) {

// error
case -1:
print "Could not fork\n";
exit;

// child
case 0:

// seperate database and curl for the child
$this->connect_database();
$this->initialize_curl();

// process the url
pcntl_exec('process_next_url_in_queue.php', array($url));

exit;

// parent
default:

// seperate database and curl for the parent
$this->connect_database();
$this->initialize_curl();
break;
}
}

Git Clone Fails with sslRead() error on OS X Yosemite

Javabrett's link got me to the answer, it revolves around Yosemite using an incorrect SSL dependency, which Git ends up using.

Installing Git via homebrew with these flags works:

brew install git --with-brewed-curl --with-brewed-openssl

Or:

brew reinstall git --with-brewed-curl --with-brewed-openssl

Fixing git HTTPS Error: bad key length on macOS 12

Unfortunately I can't provide you with a fix, but I've found a workaround for that exact same problem (company-hosted bitbucket resulting in exact same error).
I also don't know exactly why the problem occurs, but my best guess would be that the libressl library shipped with Monterey has some sort of problem with specific (?TLSv1.3) certs. This guess is because the brew-installed openssl v1.1 and v3 don't throw that error when executed with /opt/homebrew/opt/openssl/bin/openssl s_client -connect ...:443

To get around that error, I've built git from source built against different openssl and curl implementations:

  1. install autoconf, openssl and curl with brew (I think you can select the openssl lib you like, i.e. v1.1 or v3, I chose v3)
  2. clone git version you like, i.e. git clone --branch v2.33.1 https://github.com/git/git.git
  3. cd git
  4. make configure (that is why autoconf is needed)
  5. execute LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/curl/lib" CPPFLAGS="-I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/curl/include" ./configure --prefix=$HOME/git (here LDFLAGS and CPPFLAGS include the libs git will be built against, the right flags are emitted by brew on install success of curl and openssl; --prefix is the install directory of git, defaults to /usr/local but can be changed)
  6. make install
  7. ensure to add the install directory's subfolder /bin to the front of your $PATH to "override" the default git shipped by Monterey
  8. restart terminal
  9. check that git version shows the new version

This should help for now, but as I already said, this is only a workaround, hopefully Apple fixes their libressl fork ASAP.

libCurl. Cancel request while proceed

What you need to understand is that CURL is a C library. In general, you cannot pass pointers to C++ objects or functions because C does not know anything about C++'s classes and calling convention.

For example, this line is incorrect:

curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);

CURL setopt CURLOPT_ERRORBUFFER expects that the third parameter is a pointer to a C-style string (C-style char array) having space for CURL_ERROR_SIZE chars. You are instead passing a pointer to a std::string object. As CURL, being written in C, does not know what a std::string is, it simply overwrites the byte representation having sizeof (std::string) bytes with the error data because it thinks that the pointer is to a C-style char array.

Use this instead:

char errorBuffer[CURL_ERROR_SIZE + 1]; errorBuffer[CURL_ERROR_SIZE] = '\0';
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);

errorBuffer is only filled with a valid string if curl_easy_perform() returns an error code.

Also, Uploader::WriteResponce is a C++ function. With this line:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteResponce);

CURL expects the third parameter to be a pointer-to-C function. Here, you are passing a pointer-to-C++ function. You need to wrap the call to WriteResponce in an extern "C" function that calls the C++ function:

extern "C" size_t call_uploader_writeresponce(char *ptr, size_t size, size_t nmemb, void *user_data) {
return Uploader::WriteResponce(ptr, size, nmemb, static_cast<std::string *>(user_data));
}

// ...
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &call_uploader_writeresponce);

The "write function" needs to return size_t, not int; Uploader::WriteResponce needs to return size_t.

Unable to resolve unable to get local issuer certificate using git on Windows with self-signed certificate

An answer to Using makecert for Development SSL fixed this for me.

I do not know why, but the certificate created by the simple 'Create Self Signed Certificate' link in IIS Manager does not do the trick. I followed the approach in the linked question of creating and installing a self-signed CA Root; then using that to issue a Server Authentication Certificate for my server. I installed both of them in IIS.

That gets my situation the same as the blog post referenced in the original question. Once the root certificate was copy/pasted into curl-ca-bundle.crt the git/curl combo were satisfied.

How to make libcurl follow redirection by default?

No. libcurl has no default config file or anything like that.



Related Topics



Leave a reply



Submit