@@ -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+
85209static void LoadInternal (DatabaseInstance &instance) {
86210 ScalarFunctionSet http_get (" http_get" );
87211 http_get.AddFunction (ScalarFunction ({LogicalType::VARCHAR}, LogicalType::VARCHAR, HTTPGetRequestFunction));
0 commit comments