Explorar el Código

Refactored glue.

Brucey hace 3 años
padre
commit
f09dcc50db

+ 50 - 45
libcurl.mod/common.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2007-2021 Bruce A Henderson
+' Copyright (c) 2007-2022 Bruce A Henderson
 ' 
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' of this software and associated documentation files (the "Software"), to deal
@@ -40,22 +40,21 @@ Import "-framework SystemConfiguration"
 
 
 Import "libcurl/include/*.h"
-Import "curl_glue.cpp"
+Import "glue.c"
 
 Extern
 
 	Function curl_global_init:Int(flags:Int)
 	Function curl_easy_init:Byte Ptr()
-	Function curl_easy_setopt:Int(handle:Byte Ptr, option:Int, param:Byte Ptr)
 	Function curl_easy_perform:Int(handle:Byte Ptr)
 	Function curl_easy_cleanup(handle:Byte Ptr)
 	Function curl_easy_reset(handle:Byte Ptr)
 	Function curl_easy_strerror:Byte Ptr(code:Int)
-	Function curl_slist_free_all(slist:Byte Ptr)
+	Function curl_slist_free_all(slist:SCurlSlist Ptr)
 	Function curl_easy_escape:Byte Ptr(handle:Byte Ptr, s:Byte Ptr, length:Int)
 	Function curl_free(handle:Byte Ptr)
 	Function curl_easy_unescape:Byte Ptr(handle:Byte Ptr, txt:Byte Ptr, inlength:Int, outlength:Int Ptr)
-	Function curl_slist_append:Byte Ptr(slist:Byte Ptr, Text:Byte Ptr)
+	Function curl_slist_append:SCurlSlist Ptr(slist:SCurlSlist Ptr, txt:Byte Ptr)
 	
 	Function curl_multi_init:Byte Ptr()
 	Function curl_multi_cleanup(handle:Byte Ptr)
@@ -64,26 +63,25 @@ Extern
 	Function curl_multi_perform:Int(handle:Byte Ptr, running:Int Ptr)
 	Function curl_multi_info_read:Byte Ptr(handle:Byte Ptr, queuesize:Int Ptr)
 	
-	Function bmx_curl_easy_setopt_long:Int(handle:Byte Ptr, option:Int, param:Int)
+	Function bmx_curl_easy_setopt_int:Int(handle:Byte Ptr, option:Int, param:Int)
 	Function bmx_curl_easy_setopt_str:Int(handle:Byte Ptr, option:Int, param:Byte Ptr)
+	Function bmx_curl_easy_setopt_ptr:Int(handle:Byte Ptr, option:Int, param:Byte Ptr)
 	Function bmx_curl_easy_setopt_obj:Int(handle:Byte Ptr, option:Int, param:Object)
 	Function bmx_curl_easy_setopt_bbint64:Int(handle:Byte Ptr, option:Int, param:Long)
 	
-	Function bmx_curl_new_httppostPtr:Byte Ptr()
-	Function bmx_curl_formadd_name_content(httppostPtr:Byte Ptr, name:Byte Ptr, content:Byte Ptr)
-	Function bmx_curl_formadd_name_content_type(httppostPtr:Byte Ptr, name:Byte Ptr, content:Byte Ptr, t:Byte Ptr)
-	Function bmx_curl_formadd_name_file(httppostPtr:Byte Ptr, name:Byte Ptr, file:Byte Ptr, kind:Int)
-	Function bmx_curl_formadd_name_file_type(httppostPtr:Byte Ptr, name:Byte Ptr, file:Byte Ptr, t:Byte Ptr, kind:Int)
-	Function bmx_curl_formadd_name_buffer(httppostPtr:Byte Ptr, name:Byte Ptr, bname:Byte Ptr, buffer:Byte Ptr, length:Int)
-	Function bmx_curl_httppostPtr_delete(httppostPtr:Byte Ptr)
-	
-	Function bmx_curl_easy_setopt_httppost(handle:Byte Ptr, httppostPtr:Byte Ptr)
+	Function bmx_curl_formadd_name_content(httppostPtr:SCurlHttpPost Var, name:Byte Ptr, content:Byte Ptr)
+	Function bmx_curl_formadd_name_content_type(httppostPtr:SCurlHttpPost Var, name:Byte Ptr, content:Byte Ptr, t:Byte Ptr)
+	Function bmx_curl_formadd_name_file(httppostPtr:SCurlHttpPost Var, name:Byte Ptr, file:Byte Ptr, kind:Int)
+	Function bmx_curl_formadd_name_file_type(httppostPtr:SCurlHttpPost Var, name:Byte Ptr, file:Byte Ptr, t:Byte Ptr, kind:Int)
+	Function bmx_curl_formadd_name_buffer(httppostPtr:SCurlHttpPost Var, name:Byte Ptr, bname:Byte Ptr, buffer:Byte Ptr, length:Int)
+
+	Function curl_formfree(handle:Byte Ptr)
 	
 	Function bmx_curl_easy_getinfo_string:Int(handle:Byte Ptr, option:Int, b:Byte Ptr)
-	Function bmx_curl_easy_getinfo_long:Int(handle:Byte Ptr, option:Int, value:Int Ptr)
+	Function bmx_curl_easy_getinfo_int:Int(handle:Byte Ptr, option:Int, value:Int Ptr)
 	Function bmx_curl_easy_getinfo_double:Int(handle:Byte Ptr, option:Int, value:Double Ptr)
 	Function bmx_curl_easy_getinfo_obj:Object(handle:Byte Ptr, option:Int, error:Int Ptr)
-	Function bmx_curl_easy_getinfo_slist:Byte Ptr(handle:Byte Ptr, option:Int, error:Int Ptr)
+	Function bmx_curl_easy_getinfo_slist:Int(handle:Byte Ptr, option:Int, slist:SCurlSlist Var)
 	
 	Function bmx_curl_multiselect:Int(handle:Byte Ptr, timeout:Double)
 	
@@ -91,49 +89,56 @@ Extern
 	Function bmx_curl_CURLMsg_result:Int(handle:Byte Ptr)
 	Function bmx_curl_CURLMsg_easy_handle:Byte Ptr(handle:Byte Ptr)
 	
-	Function bmx_curl_get_slist:Byte Ptr(slist:Byte Ptr)
-	Function bmx_curl_slist_free(slist:Byte Ptr)
-	Function bmx_curl_get_slist_data:Byte Ptr(slist:Byte Ptr)
-	Function bmx_curl_get_slist_next:Byte Ptr(slist:Byte Ptr)
-	Function bmx_curl_slist_count:Int(slist:Byte Ptr)
-	Function bmx_curl_slist_new:Byte Ptr()
-	Function bmx_curl_add_element(slist:Byte Ptr, txt:Byte Ptr)
-	
-	Function bmx_curl_easy_setopt_slist(handle:Byte Ptr, option:Int, slist:Byte Ptr)
+	Function bmx_curl_easy_setopt_slist(handle:Byte Ptr, option:Int, slist:SCurlSlist Ptr)
 	
-	Function bmx_curl_multi_setopt_long(handle:Byte Ptr, option:Int, param:Int)
+	Function bmx_curl_multi_setopt_int(handle:Byte Ptr, option:Int, param:Int)
 	
 End Extern
 
+Type TSList
+	Field slist:SCurlSlist Ptr
+	Field count:Int
+End Type
 
-Function curlProcessSlist:String[](slistPtr:Byte Ptr)
-	If slistPtr Then
+Struct SCurlSlist
+	Field data:Byte Ptr
+	Field nxt:SCurlSlist Ptr
+End Struct
 
-		Local count:Int = bmx_curl_slist_count(slistPtr)
-		Local list:String[] = New String[count]
-		
-		Local _struct:Byte Ptr = bmx_curl_get_slist(slistPtr)
+Function curlProcessSlist:String[](slist:TSList)
+	If slist Then
+
+		Local list:String[] = New String[16]
+		Local count:Int
 		
-		For Local i:Int = 0 Until count
+		Local slistPtr:SCurlSlist Ptr = slist.slist
 		
-			Local s:Byte Ptr
-			
-			s = bmx_curl_get_slist_data(_struct)
+		While slistPtr
 		
-			If s Then
-			
-				list[i] = String.fromCString(s)
-				
+			If count = list.Length Then
+				list = list[..count * 3 / 2]
+			End If
+
+			If slistPtr.data Then
+				list[count] = String.fromUTF8String(slistPtr.data)
 			End If
 			
-			_struct = bmx_curl_get_slist_next(_struct)
-			
-		Next
+			slistPtr = slistPtr.nxt
+			count :+ 1
+
+		Wend
 		
-		bmx_curl_slist_free(slistPtr)
+		If slist.slist Then
+			curl_slist_free_all(slist.slist)
+		End If
 		
 		Return list[..count]
 
 	End If
 	Return Null
 End Function
+
+Struct SCurlHttpPost
+	Field post:Byte Ptr
+	Field last:Byte Ptr
+End Struct

+ 207 - 1
libcurl.mod/consts.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2007-2021 Bruce A Henderson
+' Copyright (c) 2007-2022 Bruce A Henderson
 ' 
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' of this software and associated documentation files (the "Software"), to deal
@@ -51,6 +51,8 @@ Const CURLOPTTYPE_OBJECTPOINT:Int = 10000
 Const CURLOPTTYPE_STRINGPOINT:Int = 10000
 Const CURLOPTTYPE_FUNCTIONPOINT:Int = 20000
 Const CURLOPTTYPE_OFF_T:Int = 30000
+Const CURLOPTTYPE_BLOB:Int = 40000
+Const CURLOPTTYPE_CBPOINT:Int = CURLOPTTYPE_OBJECTPOINT
 
 ' see CURLOPT_WRITEDATA
 Const CURLOPT_FILE:Int = CURLOPTTYPE_OBJECTPOINT + 1
@@ -1855,6 +1857,199 @@ bbdoc: Post MIME data.
 End Rem
 Const CURLOPT_MIMEPOST:Int = CURLOPTTYPE_OBJECTPOINT + 269
 
+Rem
+bbdoc:  Time to use with the CURLOPT_TIMECONDITION. Specified in number of seconds since 1 Jan 1970. 
+End Rem
+Const CURLOPT_TIMEVALUE_LARGE:Int = CURLOPTTYPE_OFF_T + 270
+
+Rem
+bbdoc:  Head start in milliseconds to give happy eyeballs. 
+End Rem
+Const CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:Int = CURLOPTTYPE_LONG + 271
+
+Rem
+bbdoc:  Function that will be called before a resolver request is made 
+End Rem
+Const CURLOPT_RESOLVER_START_FUNCTION:Int = CURLOPTTYPE_FUNCTIONPOINT + 272
+
+Rem
+bbdoc:  User data to pass to the resolver start callback. 
+End Rem
+Const CURLOPT_RESOLVER_START_DATA:Int = CURLOPTTYPE_CBPOINT + 273
+
+Rem
+bbdoc:  send HAProxy PROXY protocol header? 
+End Rem
+Const CURLOPT_HAPROXYPROTOCOL:Int = CURLOPTTYPE_LONG + 274
+
+Rem
+bbdoc:  shuffle addresses before use when DNS returns multiple 
+End Rem
+Const CURLOPT_DNS_SHUFFLE_ADDRESSES:Int = CURLOPTTYPE_LONG + 275
+
+Rem
+bbdoc:  Specify which TLS 1.3 ciphers suites to use 
+End Rem
+Const CURLOPT_TLS13_CIPHERS:Int = CURLOPTTYPE_STRINGPOINT + 276
+Const CURLOPT_PROXY_TLS13_CIPHERS:Int = CURLOPTTYPE_STRINGPOINT + 277
+
+Rem
+bbdoc:  Disallow specifying username/login in URL. 
+End Rem
+Const CURLOPT_DISALLOW_USERNAME_IN_URL:Int = CURLOPTTYPE_LONG + 278
+
+Rem
+bbdoc:  DNS-over-HTTPS URL 
+End Rem
+Const CURLOPT_DOH_URL:Int = CURLOPTTYPE_STRINGPOINT + 279
+
+Rem
+bbdoc:  Preferred buffer size to use for uploads 
+End Rem
+Const CURLOPT_UPLOAD_BUFFERSIZE:Int = CURLOPTTYPE_LONG + 280
+
+Rem
+bbdoc:  Time in ms between connection upkeep calls for long-lived connections. 
+End Rem
+Const CURLOPT_UPKEEP_INTERVAL_MS:Int = CURLOPTTYPE_LONG + 281
+
+Rem
+bbdoc:  Specify URL using CURL URL API. 
+End Rem
+Const CURLOPT_CURLU:Int = CURLOPTTYPE_OBJECTPOINT + 282
+
+Rem
+bbdoc:  add trailing data just after no more data is available 
+End Rem
+Const CURLOPT_TRAILERFUNCTION:Int = CURLOPTTYPE_FUNCTIONPOINT + 283
+
+Rem
+bbdoc:  pointer to be passed to HTTP_TRAILER_FUNCTION 
+End Rem
+Const CURLOPT_TRAILERDATA:Int = CURLOPTTYPE_CBPOINT + 284
+
+Rem
+bbdoc:  set this to 1L to allow HTTP/0.9 responses or 0L to disallow 
+End Rem
+Const CURLOPT_HTTP09_ALLOWED:Int = CURLOPTTYPE_LONG + 285
+
+Rem
+bbdoc:  alt-svc control bitmask 
+End Rem
+Const CURLOPT_ALTSVC_CTRL:Int = CURLOPTTYPE_LONG + 286
+
+Rem
+bbdoc:  alt-svc cache file name to possibly read from/write to 
+End Rem
+Const CURLOPT_ALTSVC:Int = CURLOPTTYPE_STRINGPOINT + 287
+
+Rem
+bbdoc:  maximum age (idle time) of a connection to consider it for reuse (in seconds) 
+End Rem
+Const CURLOPT_MAXAGE_CONN:Int = CURLOPTTYPE_LONG + 288
+
+Rem
+bbdoc:  SASL authorisation identity 
+End Rem
+Const CURLOPT_SASL_AUTHZID:Int = CURLOPTTYPE_STRINGPOINT + 289
+
+Rem
+bbdoc:  allow RCPT TO command to fail for some recipients 
+End Rem
+Const CURLOPT_MAIL_RCPT_ALLLOWFAILS:Int = CURLOPTTYPE_LONG + 290
+
+Rem
+bbdoc:  the private SSL-certificate as a "blob" 
+End Rem
+Const CURLOPT_SSLCERT_BLOB:Int = CURLOPTTYPE_BLOB + 291
+Const CURLOPT_SSLKEY_BLOB:Int = CURLOPTTYPE_BLOB + 292
+Const CURLOPT_PROXY_SSLCERT_BLOB:Int = CURLOPTTYPE_BLOB + 293
+Const CURLOPT_PROXY_SSLKEY_BLOB:Int = CURLOPTTYPE_BLOB + 294
+Const CURLOPT_ISSUERCERT_BLOB:Int = CURLOPTTYPE_BLOB + 295
+
+Rem
+bbdoc:  Issuer certificate for proxy 
+End Rem
+Const CURLOPT_PROXY_ISSUERCERT:Int = CURLOPTTYPE_STRINGPOINT + 296
+Const CURLOPT_PROXY_ISSUERCERT_BLOB:Int = CURLOPTTYPE_BLOB + 297
+
+Rem
+bbdoc: the EC curves requested by the TLS client (RFC 8422, 5.1);
+about: OpenSSL support via 'set_groups'/'set_curves':
+https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+End Rem
+Const CURLOPT_SSL_EC_CURVES:Int = CURLOPTTYPE_STRINGPOINT + 298
+
+Rem
+bbdoc:  HSTS bitmask 
+End Rem
+Const CURLOPT_HSTS_CTRL:Int = CURLOPTTYPE_LONG + 299
+Rem
+bbdoc:  HSTS file name 
+End Rem
+Const CURLOPT_HSTS:Int = CURLOPTTYPE_STRINGPOINT + 300
+
+Rem
+bbdoc:  HSTS read callback 
+End Rem
+Const CURLOPT_HSTSREADFUNCTION:Int = CURLOPTTYPE_FUNCTIONPOINT + 301
+Const CURLOPT_HSTSREADDATA:Int = CURLOPTTYPE_CBPOINT + 302
+
+Rem
+bbdoc:  HSTS write callback 
+End Rem
+Const CURLOPT_HSTSWRITEFUNCTION:Int = CURLOPTTYPE_FUNCTIONPOINT + 303
+Const CURLOPT_HSTSWRITEDATA:Int = CURLOPTTYPE_CBPOINT + 304
+
+Rem
+bbdoc:  Parameters for V4 signature 
+End Rem
+Const CURLOPT_AWS_SIGV4:Int = CURLOPTTYPE_STRINGPOINT + 305
+
+Rem
+bbdoc:  Same as CURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. 
+End Rem
+Const CURLOPT_DOH_SSL_VERIFYPEER:Int = CURLOPTTYPE_LONG + 306
+
+Rem
+bbdoc:  Same as CURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. 
+End Rem
+Const CURLOPT_DOH_SSL_VERIFYHOST:Int = CURLOPTTYPE_LONG + 307
+
+Rem
+bbdoc:  Same as CURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. 
+End Rem
+Const CURLOPT_DOH_SSL_VERIFYSTATUS:Int = CURLOPTTYPE_LONG + 308
+
+Rem
+bbdoc:  The CA certificates as "blob" used to validate the peer certificate this option is used only if SSL_VERIFYPEER is true 
+End Rem
+Const CURLOPT_CAINFO_BLOB:Int = CURLOPTTYPE_BLOB + 309
+
+Rem
+bbdoc:  The CA certificates as "blob" used to validate the proxy certificate this option is used only if PROXY_SSL_VERIFYPEER is true 
+End Rem
+Const CURLOPT_PROXY_CAINFO_BLOB:Int = CURLOPTTYPE_BLOB + 310
+
+Rem
+bbdoc:  used by scp/sftp to verify the host's public key 
+End Rem
+Const CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256:Int = CURLOPTTYPE_STRINGPOINT + 311
+
+Rem
+bbdoc:  Function that will be called immediately before the initial request is made on a connection (after any protocol negotiation step).  
+End Rem
+Const CURLOPT_PREREQFUNCTION:Int = CURLOPTTYPE_FUNCTIONPOINT + 312
+
+Rem
+bbdoc:  Data passed to the CURLOPT_PREREQFUNCTION callback 
+End Rem
+Const CURLOPT_PREREQDATA:Int = CURLOPTTYPE_CBPOINT + 313
+
+Rem
+bbdoc:  maximum age (since creation) of a connection to consider it for reuse (in seconds) 
+End Rem
+Const CURLOPT_MAXLIFETIME_CONN:Int = CURLOPTTYPE_LONG + 314
 
 Rem
 bbdoc: No authentication
@@ -2466,6 +2661,17 @@ Const CURLINFO_HTTP_VERSION:Int = CURLINFO_LONG + 46
 Const CURLINFO_PROXY_SSL_VERIFYRESULT:Int = CURLINFO_LONG + 47
 Const CURLINFO_PROTOCOL:Int = CURLINFO_LONG + 48
 Const CURLINFO_SCHEME:Int = CURLINFO_STRING + 49
+Const CURLINFO_TOTAL_TIME_T:Int = CURLINFO_OFF_T + 50
+Const CURLINFO_NAMELOOKUP_TIME_T:Int = CURLINFO_OFF_T + 51
+Const CURLINFO_CONNECT_TIME_T:Int = CURLINFO_OFF_T + 52
+Const CURLINFO_PRETRANSFER_TIME_T:Int = CURLINFO_OFF_T + 53
+Const CURLINFO_STARTTRANSFER_TIME_T:Int = CURLINFO_OFF_T + 54
+Const CURLINFO_REDIRECT_TIME_T:Int = CURLINFO_OFF_T + 55
+Const CURLINFO_APPCONNECT_TIME_T:Int = CURLINFO_OFF_T + 56
+Const CURLINFO_RETRY_AFTER:Int = CURLINFO_OFF_T + 57
+Const CURLINFO_EFFECTIVE_METHOD:Int = CURLINFO_STRING + 58
+Const CURLINFO_PROXY_ERROR:Int = CURLINFO_LONG + 59
+Const CURLINFO_REFERER:Int = CURLINFO_STRING + 60
 
 Const CURLCLOSEPOLICY_NONE:Int = 0 ' first, never use this
 Const CURLCLOSEPOLICY_OLDEST:Int = 1

+ 0 - 375
libcurl.mod/curl_glue.cpp

@@ -1,375 +0,0 @@
-/*
- Copyright (c) 2007-2021 Bruce A Henderson
- 
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- 
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- 
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-extern "C" {
-
-class MaxHttppost;
-class MaxSList;
-
-#include <brl.mod/blitz.mod/blitz.h>
-#include <curl/curl.h>
-
-	CURLcode bmx_curl_easy_setopt_long(CURL *curl, CURLoption option, long param);
-	CURLcode bmx_curl_easy_setopt_str(CURL *curl, CURLoption option, char * param);
-	CURLcode bmx_curl_easy_setopt_obj(CURL *curl, CURLoption option, void * param);
-	CURLcode bmx_curl_easy_setopt_bbint64(CURL *curl, CURLoption option, BBInt64 param);
-
-	MaxHttppost * bmx_curl_new_httppostPtr();
-	void bmx_curl_formadd_name_content(MaxHttppost * postPtr, const char * name, const char * content);
-	void bmx_curl_formadd_name_content_type(MaxHttppost * postPtr, const char * name, const char * content, const char * type);
-	void bmx_curl_formadd_name_file(MaxHttppost * postPtr, const char * name, const char * file, int kind);
-	void bmx_curl_formadd_name_file_type(MaxHttppost * postPtr, const char * name, const char * file, const char * type, int kind);
-	void bmx_curl_formadd_name_buffer(MaxHttppost * postPtr, const char * name, const char * bname, void * buffer, int length);
-	void bmx_curl_httppostPtr_delete(MaxHttppost * postPtr);
-	
-	void bmx_curl_easy_setopt_httppost(CURL *curl, MaxHttppost * postPtr);
-	
-	CURLcode bmx_curl_easy_getinfo_string(CURL *curl, CURLINFO info, char * s);
-	CURLcode bmx_curl_easy_getinfo_long(CURL *curl, CURLINFO info, long * value);
-	CURLcode bmx_curl_easy_getinfo_double(CURL *curl, CURLINFO info, double * value);
-	char * bmx_curl_easy_getinfo_obj(CURL * curl, CURLINFO info, CURLcode * error);
-	MaxSList * bmx_curl_easy_getinfo_slist(CURL * curl, CURLINFO info, CURLcode * error);
-	
-	int bmx_curl_multiselect(CURLM * multi, double timeout);
-	
-	CURLMSG bmx_curl_CURLMsg_msg(CURLMsg * message);
-	CURLcode bmx_curl_CURLMsg_result(CURLMsg * message);
-	CURL * bmx_curl_CURLMsg_easy_handle(CURLMsg * message);
-	
-	struct curl_slist * bmx_curl_get_slist(MaxSList * slist);
-	void bmx_curl_slist_free(MaxSList * slist);
-	char * bmx_curl_get_slist_data(curl_slist * slist);
-	curl_slist * bmx_curl_get_slist_next(curl_slist * slist);
-	int bmx_curl_slist_count(MaxSList * slist);
-	MaxSList * bmx_curl_slist_new();
-	void bmx_curl_add_element(MaxSList * slist, const char * txt);
-	
-	void bmx_curl_easy_setopt_slist(CURL *curl, CURLoption option, MaxSList * slist);
-	
-	void bmx_curl_multi_setopt_long(CURLM * multi, CURLMoption option, long value);
-}
-
-
-CURLcode bmx_curl_easy_setopt_long(CURL *curl, CURLoption option, long param) {
-	return curl_easy_setopt(curl, option, param);
-}
-
-CURLcode bmx_curl_easy_setopt_str(CURL *curl, CURLoption option, char * param) {
-	return curl_easy_setopt(curl, option, param);
-}
-
-CURLcode bmx_curl_easy_setopt_obj(CURL *curl, CURLoption option, void * param) {
-	return curl_easy_setopt(curl, option, param);
-}
-
-CURLcode bmx_curl_easy_setopt_bbint64(CURL *curl, CURLoption option, BBInt64 param) {
-	return curl_easy_setopt(curl, option, param);
-}
-
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-class MaxHttppost
-{
-public:
-	MaxHttppost();
-	~MaxHttppost();
-	
-	void formadd_name_content(const char * name, const char * content);
-	void formadd_name_content_type(const char * name, const char * content, const char * type);
-	void formadd_name_file(const char * name, const char * file, int kind);
-	void formadd_name_file_type(const char * name, const char * file, const char * type, int kind);
-	void formadd_name_buffer(const char * name, const char * bname, void * buffer, int length);
-
-	void setopt(CURL * curl);
-	
-private:
-	struct curl_httppost * post;
-	struct curl_httppost * last;
-};
-
-MaxHttppost::MaxHttppost()
-{
-	post = NULL;
-	last = NULL;
-}
-
-MaxHttppost::~MaxHttppost() {
-	curl_formfree(post);
-}
-
-
-MaxHttppost * bmx_curl_new_httppostPtr() {
-	return new MaxHttppost();
-}
-
-void MaxHttppost::formadd_name_content(const char * name, const char * content) {
-	curl_formadd(&post, &last, CURLFORM_PTRNAME, name, CURLFORM_PTRCONTENTS, content, CURLFORM_END);
-}
-
-void MaxHttppost::formadd_name_content_type(const char * name, const char * content, const char * type) {
-	curl_formadd(&post, &last, CURLFORM_PTRNAME, name, CURLFORM_PTRCONTENTS, content, CURLFORM_CONTENTTYPE, type, CURLFORM_END);
-}
-
-void MaxHttppost::formadd_name_file(const char * name, const char * file, int kind) {
-	if (kind == 1) {
-		curl_formadd(&post, &last, CURLFORM_PTRNAME, name, CURLFORM_FILE, file, CURLFORM_END);
-	} else {
-		curl_formadd(&post, &last, CURLFORM_PTRNAME, name, CURLFORM_FILECONTENT, file, CURLFORM_END);
-	}
-}
-
-void MaxHttppost::formadd_name_file_type(const char * name, const char * file, const char * type, int kind) {
-	if (kind == 1) {
-		curl_formadd(&post, &last, CURLFORM_PTRNAME, name, CURLFORM_FILE, file, CURLFORM_CONTENTTYPE, type, CURLFORM_END);
-	} else {
-		curl_formadd(&post, &last, CURLFORM_PTRNAME, name, CURLFORM_FILECONTENT, file, CURLFORM_CONTENTTYPE, type, CURLFORM_END);
-	}
-}
-
-void MaxHttppost::formadd_name_buffer(const char * name, const char * bname, void * buffer, int length) {
-	curl_formadd(&post, &last, CURLFORM_PTRNAME, name, CURLFORM_BUFFER, bname, CURLFORM_BUFFERPTR, buffer, CURLFORM_BUFFERLENGTH, length, CURLFORM_END);
-}
-
-void MaxHttppost::setopt(CURL * curl) {
-	curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
-}
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-class MaxSList
-{
-public:
-	MaxSList();
-	~MaxSList();
-	
-	struct curl_slist * getSList();
-	void setCount();
-	int getCount();
-	CURLcode getinfo(CURL * curl, CURLINFO info);
-	void addElement(const char * txt);
-	
-private:
-	struct curl_slist * slist;
-	int count;
-};
-
-MaxSList::MaxSList()
-{
-	slist = NULL;
-	count = 0;
-}
-
-MaxSList::~MaxSList() {
-	curl_slist_free_all(slist);
-}
-
-struct curl_slist * MaxSList::getSList() {
-	return slist;
-}
-
-void MaxSList::setCount() {
-	struct curl_slist * s = slist;
-	count = 0;
-   	while (s != NULL) {
-		count++;
-		s = s->next;
-     }
-}
-
-int MaxSList::getCount() {
-	return count;
-}
-
-CURLcode MaxSList::getinfo(CURL * curl, CURLINFO info) {
-	CURLcode error = curl_easy_getinfo(curl, info, &slist);
-	if (error == CURLE_OK) {
-		setCount();
-	}
-	return error;
-}
-
-void MaxSList::addElement(const char * txt) {
-	slist = curl_slist_append(slist, txt);
-}
-
-
-// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-
-void bmx_curl_formadd_name_content(MaxHttppost * postPtr, const char * name, const char * content) {
-	postPtr->formadd_name_content(name, content);
-}
-
-void bmx_curl_formadd_name_content_type(MaxHttppost * postPtr, const char * name, const char * content, const char * type){
-	postPtr->formadd_name_content_type(name, content, type);
-}
-
-void bmx_curl_formadd_name_file(MaxHttppost * postPtr, const char * name, const char * file, int kind) {
-	postPtr->formadd_name_file(name, file, kind);
-}
-
-void bmx_curl_formadd_name_file_type(MaxHttppost * postPtr, const char * name, const char * file, const char * type, int kind) {
-	postPtr->formadd_name_file_type(name, file, type, kind);
-}
-
-void bmx_curl_formadd_name_buffer(MaxHttppost * postPtr, const char * name, const char * bname, void * buffer, int length) {
-	postPtr->formadd_name_buffer(name, bname, buffer, length);
-}
-
-void bmx_curl_httppostPtr_delete(MaxHttppost * postPtr) {
-	delete postPtr;
-}
-
-void bmx_curl_easy_setopt_httppost(CURL *curl, MaxHttppost * postPtr) {
-	postPtr->setopt(curl);
-}
-
-CURLcode bmx_curl_easy_getinfo_string(CURL *curl, CURLINFO info, char * s) {
-	return curl_easy_getinfo(curl, info, s);
-
-}
-
-CURLcode bmx_curl_easy_getinfo_long(CURL *curl, CURLINFO info, long * value) {
-	return curl_easy_getinfo(curl, info, value);
-}
-
-CURLcode bmx_curl_easy_getinfo_double(CURL *curl, CURLINFO info, double * value) {
-	return curl_easy_getinfo(curl, info, value);
-}
-
-char * bmx_curl_easy_getinfo_obj(CURL * curl, CURLINFO info, CURLcode * error) {
-	char * priv = NULL;
-	*error = curl_easy_getinfo(curl, info, priv);
-	return priv;
-}
-
-int bmx_curl_multiselect(CURLM * multi, double timeout) {
-	fd_set          readfds;
-	fd_set          writefds;
-	fd_set          exceptfds;
-	int             maxfd;
-	struct timeval  to;
-	long curl_timeout = -1;
-
-	curl_multi_timeout(multi, &curl_timeout);
-
-	if (curl_timeout >=0) {
-		to.tv_sec = curl_timeout / 1000;
-		if (to.tv_sec > 1) {
-			to.tv_sec = 1;
-		} else {
-			to.tv_usec = (curl_timeout % 1000) * 1000;
-		}
-	} else {
-		unsigned long conv = (unsigned long) (timeout * 1000000.0);
-		to.tv_sec = conv / 1000000;
-		to.tv_usec = conv % 1000000;
-	}
-		
-	FD_ZERO(&readfds);
-	FD_ZERO(&writefds);
-	FD_ZERO(&exceptfds);
-
-	curl_multi_fdset(multi, &readfds, &writefds, &exceptfds, &maxfd);
-	
-	if (maxfd == -1) {
-#ifdef _WIN32
-		Sleep(100);
-		return 0;
-#else
-		struct timeval wait = { 0, 100 * 1000 };
-		return select(0, NULL, NULL, NULL, &wait);
-#endif
-	} else {
-		return select(maxfd + 1, &readfds, &writefds, &exceptfds, &to);
-	}
-}
-
-CURLMSG bmx_curl_CURLMsg_msg(CURLMsg * message) {
-	return message->msg;
-}
-
-CURLcode bmx_curl_CURLMsg_result(CURLMsg * message) {
-	return message->data.result;
-}
-
-CURL * bmx_curl_CURLMsg_easy_handle(CURLMsg * message) {
-	return message->easy_handle;
-}
-
-MaxSList * bmx_curl_easy_getinfo_slist(CURL * curl, CURLINFO info, CURLcode * error) {
-	MaxSList * mslist = new MaxSList;
-	
-	*error = mslist->getinfo(curl, info);
-	
-	return mslist;
-}
-
-MaxSList * bmx_curl_slist_new() {
-	return new MaxSList;
-}
-
-struct curl_slist * bmx_curl_get_slist(MaxSList * slist) {
-	return slist->getSList();
-}
-
-int bmx_curl_slist_count(MaxSList * slist) {
-	return slist->getCount();
-}
-
-void bmx_curl_slist_free(MaxSList * slist) {
-	delete slist;
-}
-
-char * bmx_curl_get_slist_data(struct curl_slist * slist) {
-
-	if (slist) {
-		return slist->data;
-	}
-	
-	return NULL;
-}
-
-struct curl_slist * bmx_curl_get_slist_next(struct curl_slist * slist) {
-
-	if (slist) {
-		return slist->next;
-	}
-	
-	return NULL;
-}
-
-void bmx_curl_add_element(MaxSList * slist, const char * txt) {
-	slist->addElement(txt);
-}
-
-void bmx_curl_easy_setopt_slist(CURL *curl, CURLoption option, MaxSList * slist) {
-	curl_easy_setopt(curl, option, slist->getSList());
-}
-
-void bmx_curl_multi_setopt_long(CURLM * multi, CURLMoption option, long value) {
-	curl_multi_setopt(multi, option, value);
-}
-
-
-
-

+ 83 - 76
libcurl.mod/curlmain.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2007-2021 Bruce A Henderson
+' Copyright (c) 2007-2022 Bruce A Henderson
 ' 
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' of this software and associated documentation files (the "Software"), to deal
@@ -26,7 +26,6 @@ Import BRL.LinkedList
 
 Import "common.bmx"
 
-
 Rem
 bbdoc: Sets up the program environment that libcurl needs.
 about: This will be run internally on the creation of the first #TCurlEasy with default values, but you can
@@ -52,19 +51,19 @@ Rem
 bbdoc: Returns a string describing a libcurl error code.
 End Rem
 Function CurlError:String(errorCode:Int)
-	Return String.fromCString(curl_easy_strerror(errorCode))
+	Return String.fromUTF8String(curl_easy_strerror(errorCode))
 End Function
 
 Type TCurlHasLists Abstract
 
-	Field sLists:Byte Ptr[]
+	Field sLists:TSList[]
 
 	Method freeLists()
 		If sLists Then
 		
 			For Local i:Int = 0 Until sLists.length
 			
-				bmx_curl_slist_free(sLists[i])
+				curl_slist_free_all(sLists[i].slist)
 			
 			Next
 			
@@ -128,7 +127,7 @@ Type TCurlEasy Extends TCurlHasLists
 
 	Method setOpt(option:Int, parameter:Byte Ptr)
 		If easyHandlePtr Then
-			curl_easy_setopt(easyHandlePtr, option, parameter)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, option, parameter)
 		End If
 	End Method
 
@@ -151,7 +150,7 @@ Type TCurlEasy Extends TCurlHasLists
 	End Rem
 	Method setOptInt:Int(option:Int, parameter:Int)
 		If easyHandlePtr Then
-			Return bmx_curl_easy_setopt_long(easyHandlePtr, option, parameter)
+			Return bmx_curl_easy_setopt_int(easyHandlePtr, option, parameter)
 		End If
 	End Method
 
@@ -169,7 +168,7 @@ Type TCurlEasy Extends TCurlHasLists
 	End Rem
 	Method setOptBytePtr:Int(option:Int, parameter:Byte Ptr)
 		If easyHandlePtr Then
-			Return curl_easy_setopt(easyHandlePtr, option, parameter)
+			Return bmx_curl_easy_setopt_ptr(easyHandlePtr, option, parameter)
 		End If
 	End Method
 
@@ -195,11 +194,11 @@ Type TCurlEasy Extends TCurlHasLists
 			End If
 		
 			If parameter Then
-				opt.s = parameter.toCString()
-				Return curl_easy_setopt(easyHandlePtr, option, opt.s)
+				opt.s = parameter.toUTF8String()
+				Return bmx_curl_easy_setopt_str(easyHandlePtr, option, opt.s)
 			Else
 				opt.s = Null
-				Return curl_easy_setopt(easyHandlePtr, option, Null)
+				Return bmx_curl_easy_setopt_ptr(easyHandlePtr, option, Null)
 			End If
 		End If
 	End Method
@@ -295,7 +294,7 @@ Type TCurlEasy Extends TCurlHasLists
 			setOptInt(CURLOPT_NOPROGRESS, 0)
 			
 			' set the callback
-			curl_easy_setopt(easyHandlePtr, CURLOPT_XFERINFOFUNCTION, xferinfoFunction)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_XFERINFOFUNCTION, xferinfoFunction)
 			
 			' set user data. Need to set it to at least Null so the callback doesn't send us a NULL pointer instead of a Null Object.
 			bmx_curl_easy_setopt_obj(easyHandlePtr, CURLOPT_XFERINFODATA, data)
@@ -318,7 +317,7 @@ Type TCurlEasy Extends TCurlHasLists
 			dbFunction = debugFunction
 			dbData = data
 		
-			curl_easy_setopt(easyHandlePtr, CURLOPT_DEBUGFUNCTION, dbCallback)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_DEBUGFUNCTION, dbCallback)
 			bmx_curl_easy_setopt_obj(easyHandlePtr, CURLOPT_DEBUGDATA, Self)
 		End If
 	End Method
@@ -341,7 +340,7 @@ Type TCurlEasy Extends TCurlHasLists
 	Method setWriteStream(stream:TStream)
 		If easyHandlePtr Then
 
-			curl_easy_setopt(easyHandlePtr, CURLOPT_WRITEFUNCTION, writeStreamCallback)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_WRITEFUNCTION, writeStreamCallback)
 			bmx_curl_easy_setopt_obj(easyHandlePtr, CURLOPT_WRITEDATA, stream)
 	
 		End If		
@@ -370,7 +369,7 @@ Type TCurlEasy Extends TCurlHasLists
 			wrFunction = writeFunction
 			wrData = data
 		
-			curl_easy_setopt(easyHandlePtr, CURLOPT_WRITEFUNCTION, wrCallback)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_WRITEFUNCTION, wrCallback)
 			bmx_curl_easy_setopt_obj(easyHandlePtr, CURLOPT_WRITEDATA, Self)
 		End If
 	End Method
@@ -408,7 +407,7 @@ Type TCurlEasy Extends TCurlHasLists
 	Method setReadStream(stream:TStream)
 		If easyHandlePtr Then
 
-			curl_easy_setopt(easyHandlePtr, CURLOPT_READFUNCTION, readStreamCallback)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_READFUNCTION, readStreamCallback)
 			bmx_curl_easy_setopt_obj(easyHandlePtr, CURLOPT_READDATA, stream)
 	
 		End If		
@@ -445,7 +444,7 @@ Type TCurlEasy Extends TCurlHasLists
 			rdFunction = readFunction
 			rdData = data
 		
-			curl_easy_setopt(easyHandlePtr, CURLOPT_READFUNCTION, rdCallback)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_READFUNCTION, rdCallback)
 			bmx_curl_easy_setopt_obj(easyHandlePtr, CURLOPT_READDATA, Self)
 		End If
 	End Method
@@ -485,7 +484,7 @@ Type TCurlEasy Extends TCurlHasLists
 			hrFunction = headerFunction
 			hrData = data
 		
-			curl_easy_setopt(easyHandlePtr, CURLOPT_HEADERFUNCTION, hrCallback)
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_HEADERFUNCTION, hrCallback)
 			bmx_curl_easy_setopt_obj(easyHandlePtr, CURLOPT_WRITEHEADER, Self)
 		End If
 	End Method
@@ -514,7 +513,7 @@ Type TCurlEasy Extends TCurlHasLists
 	End Rem
 	Method httpPost(formData:TCurlFormData)
 		If easyHandlePtr Then
-			bmx_curl_easy_setopt_httppost(easyHandlePtr, formData.httppostPtr);
+			bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_HTTPPOST, formData.httpPost.post);
 		End If
 	End Method
 	
@@ -545,7 +544,7 @@ Type TCurlEasy Extends TCurlHasLists
 			If headers Then
 				processArray(CURLOPT_HTTPHEADER, headers)
 			Else
-				curl_easy_setopt(easyHandlePtr, CURLOPT_HTTPHEADER, Null)
+				bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_HTTPHEADER, Null)
 			End If
 		End If
 	End Method
@@ -567,7 +566,7 @@ Type TCurlEasy Extends TCurlHasLists
 			If aliases Then
 				processArray(CURLOPT_HTTP200ALIASES, aliases)
 			Else
-				curl_easy_setopt(easyHandlePtr, CURLOPT_HTTP200ALIASES, Null)
+				bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_HTTP200ALIASES, Null)
 			End If
 		End If
 	End Method
@@ -583,7 +582,7 @@ Type TCurlEasy Extends TCurlHasLists
 			If commands Then
 				processArray(CURLOPT_PREQUOTE, commands)
 			Else
-				curl_easy_setopt(easyHandlePtr, CURLOPT_PREQUOTE, Null)
+				bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_PREQUOTE, Null)
 			End If
 		End If
 	End Method
@@ -601,7 +600,7 @@ Type TCurlEasy Extends TCurlHasLists
 			If commands Then
 				processArray(CURLOPT_QUOTE, commands)
 			Else
-				curl_easy_setopt(easyHandlePtr, CURLOPT_QUOTE, Null)
+				bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_QUOTE, Null)
 			End If
 		End If
 	End Method
@@ -617,7 +616,7 @@ Type TCurlEasy Extends TCurlHasLists
 			If commands Then
 				processArray(CURLOPT_POSTQUOTE, commands)
 			Else
-				curl_easy_setopt(easyHandlePtr, CURLOPT_POSTQUOTE, Null)
+				bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_POSTQUOTE, Null)
 			End If
 		End If
 	End Method
@@ -634,7 +633,7 @@ Type TCurlEasy Extends TCurlHasLists
 			If variables Then
 				processArray(CURLOPT_TELNETOPTIONS, variables)
 			Else
-				curl_easy_setopt(easyHandlePtr, CURLOPT_TELNETOPTIONS, Null)
+				bmx_curl_easy_setopt_ptr(easyHandlePtr, CURLOPT_TELNETOPTIONS, Null)
 			End If
 		End If
 	End Method
@@ -675,7 +674,7 @@ Type TCurlEasy Extends TCurlHasLists
 				Text = ""
 			End If
 			
-			Local s:Byte Ptr = Text.toCString()
+			Local s:Byte Ptr = Text.toUTF8String()
 			
 			Local s2:Byte Ptr = curl_easy_escape(easyHandlePtr, s, Text.length)
 			
@@ -684,7 +683,7 @@ Type TCurlEasy Extends TCurlHasLists
 
 			If s2 Then
 
-				Text = String.fromCString(s2)
+				Text = String.fromUTF8String(s2)
 
 				' free curl string
 				curl_free(s2)
@@ -708,7 +707,7 @@ Type TCurlEasy Extends TCurlHasLists
 				Text = ""
 			End If
 			
-			Local s:Byte Ptr = Text.toCString()
+			Local s:Byte Ptr = Text.toUTF8String()
 			Local out:Int
 			
 			Local s2:Byte Ptr = curl_easy_unescape(easyHandlePtr, s, Text.length, Varptr out)
@@ -745,23 +744,27 @@ Type TCurlEasy Extends TCurlHasLists
 
 		If array And array.length > 0 Then	
 
-			Local slist:Byte Ptr = bmx_curl_slist_new()
+			Local sList:TSList = New TSList
 			
 			For Local i:Int = 0 Until array.length
 			
-				Local txt:Byte Ptr = array[i].toCString()
-				
-				bmx_curl_add_element(slist, txt)
+				Local txt:Byte Ptr = array[i].toUTF8String()
 				
+				Local tmp:SCurlSlist Ptr = curl_slist_append(sList.slist, txt)
+				If tmp Then
+					sList.slist = tmp
+					sList.count :+ 1
+				End If
+
 				MemFree(txt)
 			
 			Next
 			
-			bmx_curl_easy_setopt_slist(easyHandlePtr, option, slist)
+			bmx_curl_easy_setopt_slist(easyHandlePtr, option, sList.slist)
 			
 			sLists = sLists[..sLists.length + 1]
 			
-			sLists[sLists.length - 1] = slist
+			sLists[sLists.length - 1] = sList
 	
 		End If
 	End Method
@@ -786,7 +789,7 @@ about: This is used in conjunction with the #httpPost method.
 End Rem
 Type TCurlFormData Extends TCurlHasLists 
 
-	Field httppostPtr:Byte Ptr
+	Field httppost:SCurlHttpPost
 	
 	Field count:Int = 0
 	Field ptrs:Byte Ptr[] = New Byte Ptr[0]
@@ -797,7 +800,7 @@ Type TCurlFormData Extends TCurlHasLists
 	Function Create:TCurlFormData()
 		Local this:TCurlFormData = New TCurlFormData
 		
-		this.httppostPtr = bmx_curl_new_httppostPtr()
+		'this.httppostPtr = bmx_curl_new_httppostPtr()
 		
 		Return this
 	End Function
@@ -806,20 +809,20 @@ Type TCurlFormData Extends TCurlHasLists
 	bbdoc: Add simple name/content section, with optional contenttype and/or headers.
 	End Rem
 	Method addContent(name:String, contents:String, contentType:String = Null, headers:String[] = Null)
-		Local n:Byte Ptr = name.toCString()
-		Local c:Byte Ptr = contents.toCString()
+		Local n:Byte Ptr = name.toUTF8String()
+		Local c:Byte Ptr = contents.toUTF8String()
 		Local t:Byte Ptr
 		
 		addPtr(n)
 		addPtr(c)
 		
 		If contentType Then
-			t = contentType.toCString()
+			t = contentType.toUTF8String()
 			addPtr(t)
 			
-			bmx_curl_formadd_name_content_type(httppostPtr, n, c, t)
+			bmx_curl_formadd_name_content_type(httppost, n, c, t)
 		Else
-			bmx_curl_formadd_name_content(httppostPtr, n, c)	
+			bmx_curl_formadd_name_content(httppost, n, c)	
 		End If
 		
 	End Method
@@ -828,20 +831,20 @@ Type TCurlFormData Extends TCurlHasLists
 	bbdoc: Add simple file section, with optional contenttype.
 	End Rem
 	Method addFile(name:String, file:String, contentType:String = Null, headers:String[] = Null)
-		Local n:Byte Ptr = name.toCString()
-		Local f:Byte Ptr = file.toCString()
+		Local n:Byte Ptr = name.toUTF8String()
+		Local f:Byte Ptr = file.toUTF8String()
 		Local t:Byte Ptr
 		
 		addPtr(n)
 		addPtr(f)
 		
 		If contentType Then
-			t = contentType.toCString()
+			t = contentType.toUTF8String()
 			addPtr(t)
 			
-			bmx_curl_formadd_name_file_type(httppostPtr, n, f, t, 1)
+			bmx_curl_formadd_name_file_type(httppost, n, f, t, 1)
 		Else
-			bmx_curl_formadd_name_file(httppostPtr, n, f, 1)	
+			bmx_curl_formadd_name_file(httppost, n, f, 1)	
 		End If
 	
 	End Method
@@ -850,20 +853,20 @@ Type TCurlFormData Extends TCurlHasLists
 	bbdoc: Add the @content of a file as a normal post text value, with optional contenttype.
 	End Rem
 	Method addFileContent(name:String, file:String, contentType:String = Null, headers:String[] = Null)
-		Local n:Byte Ptr = name.toCString()
-		Local f:Byte Ptr = file.toCString()
+		Local n:Byte Ptr = name.toUTF8String()
+		Local f:Byte Ptr = file.toUTF8String()
 		Local t:Byte Ptr
 		
 		addPtr(n)
 		addPtr(f)
 		
 		If contentType Then
-			t = contentType.toCString()
+			t = contentType.toUTF8String()
 			addPtr(t)
 			
-			bmx_curl_formadd_name_file_type(httppostPtr, n, f, t, 2)
+			bmx_curl_formadd_name_file_type(httppost, n, f, t, 2)
 		Else
-			bmx_curl_formadd_name_file(httppostPtr, n, f, 2)	
+			bmx_curl_formadd_name_file(httppost, n, f, 2)	
 		End If
 	
 	End Method
@@ -872,13 +875,13 @@ Type TCurlFormData Extends TCurlHasLists
 	bbdoc: Add a @buffer of @length bytes to the post.
 	End Rem
 	Method addBuffer(name:String, bufName:String, buffer:Byte Ptr, length:Int, headers:String[] = Null)
-		Local n:Byte Ptr = name.toCString()
-		Local b:Byte Ptr = bufName.toCString()
+		Local n:Byte Ptr = name.toUTF8String()
+		Local b:Byte Ptr = bufName.toUTF8String()
 		
 		addPtr(n)
 		addPtr(b)
 		
-		bmx_curl_formadd_name_buffer(httppostPtr, n, b, buffer, length)	
+		bmx_curl_formadd_name_buffer(httppost, n, b, buffer, length)	
 	End Method
 	
 	
@@ -902,9 +905,9 @@ Type TCurlFormData Extends TCurlHasLists
 	End Method
 	
 	Method free()
-		If httppostPtr Then
-			bmx_curl_httppostPtr_delete(httppostPtr)
-			httppostPtr = Null
+		If httppost.post Then
+			curl_formfree(httppost.post)
+			httppost.post = Null
 		End If
 		
 		If ptrs And count > 0 Then
@@ -951,7 +954,7 @@ Type TCurlInfo
 		error = bmx_curl_easy_getinfo_string(easyHandlePtr, CURLINFO_EFFECTIVE_URL, Varptr s)
 		
 		If Not error Then
-			Return String.fromCString(s)
+			Return String.fromUTF8String(s)
 		End If
 		
 		Return Null
@@ -965,7 +968,7 @@ Type TCurlInfo
 	Method responseCode:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_RESPONSE_CODE, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_RESPONSE_CODE, Varptr value)
 		
 		Return value
 	End Method
@@ -976,7 +979,7 @@ Type TCurlInfo
 	Method httpConnectCode:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_FILETIME, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_FILETIME, Varptr value)
 		
 		Return value
 	End Method
@@ -991,7 +994,7 @@ Type TCurlInfo
 	Method FileTime:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_HTTPAUTH_AVAIL, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_HTTPAUTH_AVAIL, Varptr value)
 		
 		Return value
 	End Method
@@ -1072,7 +1075,7 @@ Type TCurlInfo
 	Method redirectCount:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_REDIRECT_COUNT, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_REDIRECT_COUNT, Varptr value)
 		
 		Return value
 	End Method
@@ -1131,7 +1134,7 @@ Type TCurlInfo
 	Method headerSize:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_HEADER_SIZE, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_HEADER_SIZE, Varptr value)
 		
 		Return value
 	End Method
@@ -1144,7 +1147,7 @@ Type TCurlInfo
 	Method requestSize:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_REQUEST_SIZE, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_REQUEST_SIZE, Varptr value)
 		
 		Return value
 	End Method
@@ -1155,7 +1158,7 @@ Type TCurlInfo
 	Method sslVerifyResult:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_SSL_VERIFYRESULT, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_SSL_VERIFYRESULT, Varptr value)
 		
 		Return value
 	End Method
@@ -1167,8 +1170,10 @@ Type TCurlInfo
 	End Rem
 	Method sslEngines:String[]()
 		
-		Return curlProcessSlist(bmx_curl_easy_getinfo_slist(easyHandlePtr, CURLINFO_SSL_ENGINES, Varptr error))
-		
+		Local slist:TSList = New TSList
+		error = bmx_curl_easy_getinfo_slist(easyHandlePtr, CURLINFO_SSL_ENGINES, slist.slist)
+		Return curlProcessSlist(slist)
+
 	End Method
 	
 	Rem
@@ -1206,7 +1211,7 @@ Type TCurlInfo
 		
 		If Not error Then
 			If s Then
-				Return String.fromCString(s)
+				Return String.fromUTF8String(s)
 			End If
 		End If
 		
@@ -1227,7 +1232,7 @@ Type TCurlInfo
 	Method httpAuthAvail:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_HTTPAUTH_AVAIL, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_HTTPAUTH_AVAIL, Varptr value)
 		
 		Return value
 	End Method
@@ -1239,7 +1244,7 @@ Type TCurlInfo
 	Method proxyAuthAvail:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_PROXYAUTH_AVAIL, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_PROXYAUTH_AVAIL, Varptr value)
 		
 		Return value
 	End Method
@@ -1250,7 +1255,7 @@ Type TCurlInfo
 	Method osErrno:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_OS_ERRNO, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_OS_ERRNO, Varptr value)
 		
 		Return value
 	End Method
@@ -1263,7 +1268,7 @@ Type TCurlInfo
 	Method numConnects:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_NUM_CONNECTS, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_NUM_CONNECTS, Varptr value)
 		
 		Return value
 	End Method
@@ -1275,7 +1280,9 @@ Type TCurlInfo
 	End Rem
 	Method cookieList:String[]()
 
-		Return curlProcessSlist(bmx_curl_easy_getinfo_slist(easyHandlePtr, CURLINFO_COOKIELIST, Varptr error))
+		Local slist:TSList = New TSList
+		error = bmx_curl_easy_getinfo_slist(easyHandlePtr, CURLINFO_COOKIELIST, slist.slist)
+		Return curlProcessSlist(slist)
 
 	End Method
 	
@@ -1288,7 +1295,7 @@ Type TCurlInfo
 	Method lastSocket:Int()
 		Local value:Int
 		
-		error = bmx_curl_easy_getinfo_long(easyHandlePtr, CURLINFO_LASTSOCKET, Varptr value)
+		error = bmx_curl_easy_getinfo_int(easyHandlePtr, CURLINFO_LASTSOCKET, Varptr value)
 		
 		Return value
 	End Method
@@ -1305,7 +1312,7 @@ Type TCurlInfo
 		
 		If Not error Then
 			If s Then
-				Return String.fromCString(s)
+				Return String.fromUTF8String(s)
 			End If
 		End If
 		
@@ -1595,7 +1602,7 @@ Type TCurlMulti
 	End Rem
 	Method multiSetOptInt(option:Int, parameter:Int)
 		If multiHandlePtr Then
-			bmx_curl_multi_setopt_long(multiHandlePtr, option, parameter)
+			bmx_curl_multi_setopt_int(multiHandlePtr, option, parameter)
 		End If
 	End Method
 	

+ 168 - 0
libcurl.mod/glue.c

@@ -0,0 +1,168 @@
+/*
+ Copyright (c) 2007-2022 Bruce A Henderson
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ 
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+
+#include <brl.mod/blitz.mod/blitz.h>
+#include <curl/curl.h>
+
+struct curlHttpPost {
+    struct curl_httppost * post;
+	struct curl_httppost * last;
+};
+
+
+int bmx_curl_easy_setopt_int(CURL *curl, int option, int param) {
+	return curl_easy_setopt(curl, option, param);
+}
+
+int bmx_curl_easy_setopt_str(CURL *curl, int option, char * param) {
+	return curl_easy_setopt(curl, option, param);
+}
+
+int bmx_curl_easy_setopt_obj(CURL *curl, int option, BBObject * param) {
+	return curl_easy_setopt(curl, option, param);
+}
+
+int bmx_curl_easy_setopt_ptr(CURL *curl, int option, void * param) {
+	return curl_easy_setopt(curl, option, param);
+}
+
+int bmx_curl_easy_setopt_bbint64(CURL *curl, int option, BBInt64 param) {
+	return curl_easy_setopt(curl, option, param);
+}
+
+void bmx_curl_formadd_name_content(struct curlHttpPost * httpPost, const char * name, const char * content) {
+	curl_formadd(&httpPost->post, &httpPost->last, CURLFORM_PTRNAME, name, CURLFORM_PTRCONTENTS, content, CURLFORM_END);
+}
+
+void bmx_curl_formadd_name_content_type(struct curlHttpPost * httpPost, const char * name, const char * content, const char * type) {
+	curl_formadd(&httpPost->post, &httpPost->last, CURLFORM_PTRNAME, name, CURLFORM_PTRCONTENTS, content, CURLFORM_CONTENTTYPE, type, CURLFORM_END);
+}
+
+void bmx_curl_formadd_name_file(struct curlHttpPost * httpPost, const char * name, const char * file, int kind) {
+	if (kind == 1) {
+		curl_formadd(&httpPost->post, &httpPost->last, CURLFORM_PTRNAME, name, CURLFORM_FILE, file, CURLFORM_END);
+	} else {
+		curl_formadd(&httpPost->post, &httpPost->last, CURLFORM_PTRNAME, name, CURLFORM_FILECONTENT, file, CURLFORM_END);
+	}
+}
+
+void bmx_curl_formadd_name_file_type(struct curlHttpPost * httpPost, const char * name, const char * file, const char * type, int kind) {
+	if (kind == 1) {
+		curl_formadd(&httpPost->post, &httpPost->last, CURLFORM_PTRNAME, name, CURLFORM_FILE, file, CURLFORM_CONTENTTYPE, type, CURLFORM_END);
+	} else {
+		curl_formadd(&httpPost->post, &httpPost->last, CURLFORM_PTRNAME, name, CURLFORM_FILECONTENT, file, CURLFORM_CONTENTTYPE, type, CURLFORM_END);
+	}
+}
+
+void bmx_curl_formadd_name_buffer(struct curlHttpPost * httpPost, const char * name, const char * bname, void * buffer, int length) {
+	curl_formadd(&httpPost->post, &httpPost->last, CURLFORM_PTRNAME, name, CURLFORM_BUFFER, bname, CURLFORM_BUFFERPTR, buffer, CURLFORM_BUFFERLENGTH, length, CURLFORM_END);
+}
+
+void bmx_curl_setopt(struct curlHttpPost * httpPost, CURL * curl) {
+	curl_easy_setopt(curl, CURLOPT_HTTPPOST, httpPost->post);
+}
+
+CURLcode bmx_curl_easy_getinfo_string(CURL *curl, CURLINFO info, char * s) {
+	return curl_easy_getinfo(curl, info, s);
+
+}
+
+CURLcode bmx_curl_easy_getinfo_int(CURL *curl, CURLINFO info, int * value) {
+	return curl_easy_getinfo(curl, info, value);
+}
+
+CURLcode bmx_curl_easy_getinfo_double(CURL *curl, CURLINFO info, double * value) {
+	return curl_easy_getinfo(curl, info, value);
+}
+
+char * bmx_curl_easy_getinfo_obj(CURL * curl, CURLINFO info, CURLcode * error) {
+	char * priv = NULL;
+	*error = curl_easy_getinfo(curl, info, priv);
+	return priv;
+}
+
+int bmx_curl_multiselect(CURLM * multi, double timeout) {
+	fd_set          readfds;
+	fd_set          writefds;
+	fd_set          exceptfds;
+	int             maxfd;
+	struct timeval  to;
+	long curl_timeout = -1;
+
+	curl_multi_timeout(multi, &curl_timeout);
+
+	if (curl_timeout >=0) {
+		to.tv_sec = curl_timeout / 1000;
+		if (to.tv_sec > 1) {
+			to.tv_sec = 1;
+		} else {
+			to.tv_usec = (curl_timeout % 1000) * 1000;
+		}
+	} else {
+		unsigned long conv = (unsigned long) (timeout * 1000000.0);
+		to.tv_sec = conv / 1000000;
+		to.tv_usec = conv % 1000000;
+	}
+		
+	FD_ZERO(&readfds);
+	FD_ZERO(&writefds);
+	FD_ZERO(&exceptfds);
+
+	curl_multi_fdset(multi, &readfds, &writefds, &exceptfds, &maxfd);
+	
+	if (maxfd == -1) {
+#ifdef _WIN32
+		Sleep(100);
+		return 0;
+#else
+		struct timeval wait = { 0, 100 * 1000 };
+		return select(0, NULL, NULL, NULL, &wait);
+#endif
+	} else {
+		return select(maxfd + 1, &readfds, &writefds, &exceptfds, &to);
+	}
+}
+
+CURLMSG bmx_curl_CURLMsg_msg(CURLMsg * message) {
+	return message->msg;
+}
+
+CURLcode bmx_curl_CURLMsg_result(CURLMsg * message) {
+	return message->data.result;
+}
+
+CURL * bmx_curl_CURLMsg_easy_handle(CURLMsg * message) {
+	return message->easy_handle;
+}
+
+CURLcode bmx_curl_easy_getinfo_slist(CURL * curl, CURLINFO info, struct curl_slist * list) {
+    return curl_easy_getinfo(curl, info, list);
+}
+
+void bmx_curl_easy_setopt_slist(CURL *curl, CURLoption option, struct curl_slist * slist) {
+	curl_easy_setopt(curl, option, slist);
+}
+
+void bmx_curl_multi_setopt_int(CURLM * multi, CURLMoption option, int value) {
+	curl_multi_setopt(multi, option, value);
+}

+ 5 - 3
libcurl.mod/libcurl.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2007-2021 Bruce A Henderson
+' Copyright (c) 2007-2022 Bruce A Henderson
 ' 
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' of this software and associated documentation files (the "Software"), to deal
@@ -25,14 +25,16 @@ bbdoc: libcurl with SSL
 End Rem
 Module Net.libcurl
 
-ModuleInfo "Version: 1.07"
+ModuleInfo "Version: 1.08"
 ModuleInfo "Author: Bruce A Henderson"
 ModuleInfo "License: MIT"
 ModuleInfo "Copyright: (libcurl) 1996 - 2021, Daniel Stenberg"
 ModuleInfo "Copyright: (c-ares) 1998 Massachusetts Institute of Technology, 2004 - 2021 by Daniel Stenberg et al"
-ModuleInfo "Copyright: (Wrapper) 2007-2021 Bruce A Henderson"
+ModuleInfo "Copyright: (Wrapper) 2007-2022 Bruce A Henderson"
 ModuleInfo "Modserver: BRL"
 
+ModuleInfo "History: 1.08"
+ModuleInfo "History: Refactored glue."
 ModuleInfo "History: 1.07"
 ModuleInfo "History: Update to libcurl 7.80.0"
 ModuleInfo "History: Update to c-ares 1.18.1"

+ 3 - 8
libcurl.mod/source.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2007-2021 Bruce A Henderson
+' Copyright (c) 2007-2022 Bruce A Henderson
 ' 
 ' Permission is hereby granted, free of charge, to any person obtaining a copy
 ' of this software and associated documentation files (the "Software"), to deal
@@ -24,13 +24,8 @@ Import Net.libssh2
 Import Net.mbedtls
 Import "../mbedtls.mod/mbedtls/include/*.h"
 
-?win32
-'Import "ssl/include/*.h"
-?
-
-'?Not macos
-Import "../libssh2.mod/include_all/*.h"
-'?
+Import "../libssh2.mod/libssh2/src/*.h"
+Import "../libssh2.mod/libssh2/include/*.h"
 
 'Import "c-ares/include/*.h"
 

+ 27 - 0
libcurl.mod/tests/test.bmx

@@ -0,0 +1,27 @@
+SuperStrict
+
+Framework brl.standardio
+Import net.libcurl
+Import BRL.MaxUnit
+
+New TTestSuite.run()
+
+Type TSListTest Extends TTest
+
+	Method Test() { test }
+		Local curl:TCurlEasy = TCurlEasy.Create()
+
+		Local arr:String[] = ["one", "two", "three"]
+
+		curl.processArray(CURLOPT_HTTPHEADER, arr)
+
+		Local res:String[] = curlProcessSlist(curl.slists[0])
+
+		AssertEquals(arr.Length, res.Length)
+
+		For Local i:Int = 0 Until arr.Length
+			AssertEquals(arr[i], res[i])
+		Next
+	End Method
+
+End Type