Skip to content

Commit 677790d

Browse files
committed
fix
1 parent 69d855a commit 677790d

File tree

1 file changed

+136
-12
lines changed

1 file changed

+136
-12
lines changed

src/http_client_extension.cpp

Lines changed: 136 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,80 @@ static void HTTPGetRequestFunction(DataChunk &args, ExpressionState &state, Vect
2020

2121
UnaryExecutor::Execute<string_t, string_t>(args.data[0], result, args.size(), [&](string_t input) {
2222
std::string url = input.GetString();
23-
duckdb_httplib_openssl::Client client(url);
2423

25-
auto res = client.Get("/");
24+
// Parse the URL to extract the domain and path
25+
std::string scheme, domain, path;
26+
size_t pos = url.find("://");
27+
if (pos != std::string::npos) {
28+
scheme = url.substr(0, pos);
29+
url.erase(0, pos + 3);
30+
}
31+
32+
pos = url.find("/");
33+
if (pos != std::string::npos) {
34+
domain = url.substr(0, pos);
35+
path = url.substr(pos);
36+
} else {
37+
domain = url;
38+
path = "/";
39+
}
40+
41+
// Create client and set a reasonable timeout (e.g., 10 seconds)
42+
duckdb_httplib_openssl::Client client(domain.c_str());
43+
client.set_read_timeout(10, 0); // 10 seconds
44+
45+
// Make the GET request
46+
auto res = client.Get(path.c_str());
2647
if (res) {
2748
if (res->status == 200) {
2849
return StringVector::AddString(result, res->body);
2950
} else {
30-
throw std::runtime_error("HTTP error: " + std::to_string(res->status));
51+
throw std::runtime_error("HTTP error: " + std::to_string(res->status) + " - " + res->reason);
3152
}
3253
} else {
33-
auto err = res.error();
34-
throw std::runtime_error("HTTP error: " + duckdb_httplib_openssl::to_string(err)); // Fully qualify to_string
54+
// Handle the error case
55+
std::string err_message = "HTTP request failed. ";
56+
57+
// Convert httplib error codes to a descriptive message
58+
switch (res.error()) {
59+
case duckdb_httplib_openssl::Error::Connection:
60+
err_message += "Connection error.";
61+
break;
62+
case duckdb_httplib_openssl::Error::BindIPAddress:
63+
err_message += "Failed to bind IP address.";
64+
break;
65+
case duckdb_httplib_openssl::Error::Read:
66+
err_message += "Error reading response.";
67+
break;
68+
case duckdb_httplib_openssl::Error::Write:
69+
err_message += "Error writing request.";
70+
break;
71+
case duckdb_httplib_openssl::Error::ExceedRedirectCount:
72+
err_message += "Too many redirects.";
73+
break;
74+
case duckdb_httplib_openssl::Error::Canceled:
75+
err_message += "Request was canceled.";
76+
break;
77+
case duckdb_httplib_openssl::Error::SSLConnection:
78+
err_message += "SSL connection failed.";
79+
break;
80+
case duckdb_httplib_openssl::Error::SSLLoadingCerts:
81+
err_message += "Failed to load SSL certificates.";
82+
break;
83+
case duckdb_httplib_openssl::Error::SSLServerVerification:
84+
err_message += "SSL server verification failed.";
85+
break;
86+
case duckdb_httplib_openssl::Error::UnsupportedMultipartBoundaryChars:
87+
err_message += "Unsupported characters in multipart boundary.";
88+
break;
89+
case duckdb_httplib_openssl::Error::Compression:
90+
err_message += "Error during compression.";
91+
break;
92+
default:
93+
err_message += "Unknown error.";
94+
break;
95+
}
96+
throw std::runtime_error(err_message);
3597
}
3698
});
3799
}
@@ -47,11 +109,30 @@ static void HTTPPostRequestFunction(DataChunk &args, ExpressionState &state, Vec
47109
url_vector, headers_vector, body_vector, result, args.size(),
48110
[&](string_t url, string_t headers, string_t body) {
49111
std::string url_str = url.GetString();
50-
duckdb_httplib_openssl::Client client(url_str);
51112

52-
// HeaderMap header_map = {};
113+
// Parse the URL to extract the domain and path
114+
std::string scheme, domain, path;
115+
size_t pos = url_str.find("://");
116+
if (pos != std::string::npos) {
117+
scheme = url_str.substr(0, pos);
118+
url_str.erase(0, pos + 3);
119+
}
120+
121+
pos = url_str.find("/");
122+
if (pos != std::string::npos) {
123+
domain = url_str.substr(0, pos);
124+
path = url_str.substr(pos);
125+
} else {
126+
domain = url_str;
127+
path = "/";
128+
}
53129

54-
duckdb_httplib_openssl::Headers header_map; // Fully qualified httplib::Headers
130+
// Create the client and set a timeout (e.g., 10 seconds)
131+
duckdb_httplib_openssl::Client client(domain.c_str());
132+
client.set_read_timeout(10, 0); // 10 seconds
133+
134+
// Prepare headers
135+
duckdb_httplib_openssl::Headers header_map;
55136
std::istringstream header_stream(headers.GetString());
56137
std::string header;
57138
while (std::getline(header_stream, header)) {
@@ -68,20 +149,63 @@ static void HTTPPostRequestFunction(DataChunk &args, ExpressionState &state, Vec
68149
}
69150
}
70151

71-
auto res = client.Post("/", header_map, body.GetString(), "application/json");
152+
// Make the POST request with headers and body
153+
auto res = client.Post(path.c_str(), header_map, body.GetString(), "application/json");
72154
if (res) {
73155
if (res->status == 200) {
74156
return StringVector::AddString(result, res->body);
75157
} else {
76-
throw std::runtime_error("HTTP error: " + std::to_string(res->status));
158+
throw std::runtime_error("HTTP error: " + std::to_string(res->status) + " - " + res->reason);
77159
}
78160
} else {
79-
auto err = res.error();
80-
throw std::runtime_error("HTTP error: " + duckdb_httplib_openssl::to_string(err)); // Fully qualify to_string
161+
// Handle the error case
162+
std::string err_message = "HTTP POST request failed. ";
163+
164+
// Convert httplib error codes to a descriptive message
165+
switch (res.error()) {
166+
case duckdb_httplib_openssl::Error::Connection:
167+
err_message += "Connection error.";
168+
break;
169+
case duckdb_httplib_openssl::Error::BindIPAddress:
170+
err_message += "Failed to bind IP address.";
171+
break;
172+
case duckdb_httplib_openssl::Error::Read:
173+
err_message += "Error reading response.";
174+
break;
175+
case duckdb_httplib_openssl::Error::Write:
176+
err_message += "Error writing request.";
177+
break;
178+
case duckdb_httplib_openssl::Error::ExceedRedirectCount:
179+
err_message += "Too many redirects.";
180+
break;
181+
case duckdb_httplib_openssl::Error::Canceled:
182+
err_message += "Request was canceled.";
183+
break;
184+
case duckdb_httplib_openssl::Error::SSLConnection:
185+
err_message += "SSL connection failed.";
186+
break;
187+
case duckdb_httplib_openssl::Error::SSLLoadingCerts:
188+
err_message += "Failed to load SSL certificates.";
189+
break;
190+
case duckdb_httplib_openssl::Error::SSLServerVerification:
191+
err_message += "SSL server verification failed.";
192+
break;
193+
case duckdb_httplib_openssl::Error::UnsupportedMultipartBoundaryChars:
194+
err_message += "Unsupported characters in multipart boundary.";
195+
break;
196+
case duckdb_httplib_openssl::Error::Compression:
197+
err_message += "Error during compression.";
198+
break;
199+
default:
200+
err_message += "Unknown error.";
201+
break;
202+
}
203+
throw std::runtime_error(err_message);
81204
}
82205
});
83206
}
84207

208+
85209
static void LoadInternal(DatabaseInstance &instance) {
86210
ScalarFunctionSet http_get("http_get");
87211
http_get.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR, HTTPGetRequestFunction));

0 commit comments

Comments
 (0)