Skip to content

Commit c5b7ed4

Browse files
authored
Merge pull request #7 from hatamiarash7/fix/curl-ca
Fix cURL CA
2 parents b3edf74 + 7474406 commit c5b7ed4

File tree

8 files changed

+100
-39
lines changed

8 files changed

+100
-39
lines changed

.github/workflows/MainDistributionPipeline.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ jobs:
2525

2626
duckdb-stable-build:
2727
name: Build extension binaries
28-
uses: duckdb/extension-ci-tools/.github/workflows/[email protected].1
28+
uses: duckdb/extension-ci-tools/.github/workflows/[email protected].2
2929
with:
30-
duckdb_version: v1.2.1
31-
ci_tools_version: v1.2.1
30+
duckdb_version: v1.2.2
31+
ci_tools_version: v1.2.2
3232
extension_name: netquack

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ This extension provides various functions for manipulating and analyzing IP addr
334334

335335
#### IP Calculator
336336

337+
> [!WARNING]
338+
> It's an experimental function.
339+
337340
The `ipcalc` function takes an IP address and netmask and calculates the resulting broadcast, network, wildcard mask, and host range.
338341

339342
![ipcalc-sc](./.github/ipcalc-sc.png)
@@ -369,9 +372,6 @@ D SELECT i.IP,
369372
└────────────────┴───────┘
370373
```
371374

372-
> [!WARNING]
373-
> It's an experimental function.
374-
375375
### Get Extension Version
376376

377377
You can use the `netquack_version` function to get the extension version.
@@ -382,7 +382,7 @@ D select * from netquack_version();
382382
│ version │
383383
varchar
384384
├─────────┤
385-
v1.2.0
385+
v1.4.0
386386
└─────────┘
387387
```
388388

duckdb

Submodule duckdb updated 156 files

src/functions/get_tranco.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace duckdb
1414
// Function to get the download code for the Tranco list
1515
std::string GetTrancoDownloadCode (char *date)
1616
{
17-
CURL *curl;
17+
CURL *curl = CreateCurlHandler ();
1818
CURLcode res;
1919
std::string readBuffer;
2020

@@ -23,21 +23,15 @@ namespace duckdb
2323

2424
LogMessage ("INFO", "Get Tranco download code for date: " + std::string (date));
2525

26-
curl = curl_easy_init ();
27-
if (curl)
26+
curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
27+
curl_easy_setopt (curl, CURLOPT_WRITEDATA, &readBuffer);
28+
res = curl_easy_perform (curl);
29+
curl_easy_cleanup (curl);
30+
31+
if (res != CURLE_OK)
2832
{
29-
curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
30-
curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); // Follow redirects
31-
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, WriteCallback);
32-
curl_easy_setopt (curl, CURLOPT_WRITEDATA, &readBuffer);
33-
res = curl_easy_perform (curl);
34-
curl_easy_cleanup (curl);
35-
36-
if (res != CURLE_OK)
37-
{
38-
LogMessage ("ERROR", "Failed to fetch Tranco download code: " + std::string (curl_easy_strerror (res)));
39-
throw std::runtime_error ("Failed to fetch Tranco download code.");
40-
}
33+
LogMessage ("ERROR", "Failed to fetch Tranco download code: " + std::string (curl_easy_strerror (res)));
34+
throw std::runtime_error ("Failed to fetch Tranco download code.");
4135
}
4236

4337
// Extract the download code from the URL

src/functions/get_version.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace duckdb
4343

4444
output.SetCardinality (1);
4545
// Set version
46-
output.data[0].SetValue (0, "v1.1.0");
46+
output.data[0].SetValue (0, "v1.4.0");
4747
// Set done
4848
auto &local_state = (VersionLocalState &)*data_p.local_state;
4949
local_state.done = true;

src/utils/utils.cpp

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,77 @@
88
#include <regex>
99
#include <sstream>
1010

11+
#ifdef _WIN32
12+
#include <windows.h>
13+
#else // POSIX
14+
#include <sys/stat.h>
15+
#endif
16+
1117
namespace duckdb
1218
{
1319
namespace netquack
1420
{
21+
bool file_exists (const char *file_path)
22+
{
23+
#ifdef _WIN32
24+
DWORD attributes = GetFileAttributesA (file_path);
25+
return (attributes != INVALID_FILE_ATTRIBUTES);
26+
#else // POSIX
27+
struct stat buffer;
28+
return (stat (file_path, &buffer) == 0);
29+
#endif
30+
}
31+
32+
CURL *CreateCurlHandler ()
33+
{
34+
CURL *curl = curl_easy_init ();
35+
if (!curl)
36+
{
37+
throw std::runtime_error ("Failed to initialize CURL");
38+
}
39+
40+
const char *ca_info = std::getenv ("CURL_CA_INFO");
41+
#if !defined(_WIN32) && !defined(__APPLE__)
42+
if (!ca_info)
43+
{
44+
// Check for common CA certificate bundle locations on Linux
45+
for (const auto *path : {
46+
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
47+
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
48+
"/etc/ssl/ca-bundle.pem", // OpenSUSE
49+
"/etc/pki/tls/cacert.pem", // OpenELEC
50+
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
51+
"/etc/ssl/cert.pem" // Alpine Linux
52+
})
53+
{
54+
if (file_exists (path))
55+
{
56+
ca_info = path;
57+
break;
58+
}
59+
}
60+
}
61+
#endif
62+
curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); // Follow redirects
63+
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, WriteCallback);
64+
if (ca_info)
65+
{
66+
// Set the custom CA certificate bundle file
67+
// https://github.com/hatamiarash7/duckdb-netquack/issues/6
68+
LogMessage ("DEBUG", "Using custom CA certificate bundle: " + std::string (ca_info));
69+
curl_easy_setopt (curl, CURLOPT_CAINFO, ca_info);
70+
}
71+
const char *ca_path = std::getenv ("CURL_CA_PATH");
72+
if (ca_path)
73+
{
74+
// Set the custom CA certificate directory
75+
LogMessage ("DEBUG", "Using custom CA certificate directory: " + std::string (ca_path));
76+
curl_easy_setopt (curl, CURLOPT_CAPATH, ca_path);
77+
}
78+
79+
return curl;
80+
}
81+
1582
void LogMessage (const std::string &level, const std::string &message)
1683
{
1784
std::ofstream log_file ("netquack.log", std::ios_base::app);
@@ -31,24 +98,19 @@ namespace duckdb
3198

3299
std::string DownloadPublicSuffixList ()
33100
{
34-
CURL *curl;
101+
CURL *curl = CreateCurlHandler ();
35102
CURLcode res;
36103
std::string readBuffer;
37104

38-
curl = curl_easy_init ();
39-
if (curl)
40-
{
41-
curl_easy_setopt (curl, CURLOPT_URL, "https://publicsuffix.org/list/public_suffix_list.dat");
42-
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, WriteCallback);
43-
curl_easy_setopt (curl, CURLOPT_WRITEDATA, &readBuffer);
44-
res = curl_easy_perform (curl);
45-
curl_easy_cleanup (curl);
105+
curl_easy_setopt (curl, CURLOPT_URL, "https://publicsuffix.org/list/public_suffix_list.dat");
106+
curl_easy_setopt (curl, CURLOPT_WRITEDATA, &readBuffer);
107+
res = curl_easy_perform (curl);
108+
curl_easy_cleanup (curl);
46109

47-
if (res != CURLE_OK)
48-
{
49-
LogMessage ("ERROR", "Failed to download public suffix list: " + std::string (curl_easy_strerror (res)));
50-
throw std::runtime_error ("Failed to download public suffix list. Check logs for details.");
51-
}
110+
if (res != CURLE_OK)
111+
{
112+
LogMessage ("ERROR", "Failed to download public suffix list: " + std::string (curl_easy_strerror (res)));
113+
throw std::runtime_error ("Failed to download public suffix list. Check logs for details.");
52114
}
53115

54116
return readBuffer;

src/utils/utils.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
#pragma once
22

3+
#include <curl/curl.h>
4+
35
#include "duckdb.hpp"
46

57
namespace duckdb
68
{
79
namespace netquack
810
{
11+
// Function to get a CURL handler
12+
CURL *CreateCurlHandler ();
13+
914
// Function to log messages with a specified log level
1015
void LogMessage (const std::string &level, const std::string &message);
1116

0 commit comments

Comments
 (0)