From fddb1fa13a58d135929ff99b3a26d9d59903b3b4 Mon Sep 17 00:00:00 2001 From: Sorin Otescu Date: Fri, 14 Jun 2019 14:07:59 +0300 Subject: [PATCH 1/3] Fix _Ctype_struct_curl_slist --- easy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easy.go b/easy.go index e0cec43..fe28330 100644 --- a/easy.go +++ b/easy.go @@ -405,7 +405,7 @@ func (curl *CURL) Getinfo(info CurlInfo) (ret interface{}, err error) { debugf("Getinfo %s", ret) return ret, err case C.CURLINFO_SLIST: - a_ptr_slist := new(_Ctype_struct_curl_slist) + a_ptr_slist := new(C.struct_curl_slist) err := newCurlError(C.curl_easy_getinfo_slist(p, cInfo, &a_ptr_slist)) ret := []string{} for a_ptr_slist != nil { From f0f8963a126eca26dfa50c433125c3a3318c784f Mon Sep 17 00:00:00 2001 From: Sorin Otescu Date: Fri, 14 Jun 2019 14:51:14 +0300 Subject: [PATCH 2/3] Add CURLM Wait() --- examples/multi_and_wait.go | 66 ++++++++++++++++++++++++++++++++++++++ multi.go | 8 +++++ 2 files changed, 74 insertions(+) create mode 100644 examples/multi_and_wait.go diff --git a/examples/multi_and_wait.go b/examples/multi_and_wait.go new file mode 100644 index 0000000..4f500f0 --- /dev/null +++ b/examples/multi_and_wait.go @@ -0,0 +1,66 @@ +package main + +import ( + "fmt" + "github.com/sorinescu/go-curl" + "time" +) + +func main() { + ch1 := curl.EasyInit() + ch2 := curl.EasyInit() + + ch1.Setopt(curl.OPT_URL, "http://www.163.com") + ch1.Setopt(curl.OPT_HEADER, 0) + ch1.Setopt(curl.OPT_VERBOSE, true) + ch2.Setopt(curl.OPT_URL, "http://www.baidu.com") + ch2.Setopt(curl.OPT_HEADER, 0) + ch2.Setopt(curl.OPT_VERBOSE, true) + + mh := curl.MultiInit() + + mh.AddHandle(ch1) + mh.AddHandle(ch2) + + var repeats int + + for { + stillRunning, err := mh.Perform() + if err != nil { + fmt.Printf("Error perform: %s\n", err) + break + } else if stillRunning > 0 { + fmt.Printf("Still running: %d\n", stillRunning) + } else { + break + } + + timeoutMs := 1000 + curlTimeout, err := mh.Timeout() + if err != nil { + fmt.Printf("Error multi_timeout: %s\n", err) + } + if curlTimeout >= 0 { + timeoutMs = curlTimeout + } + + numFds, err := mh.Wait(timeoutMs) + if err != nil { + fmt.Printf("Error wait: %s\n", err) + break + } + + // 'numFds' being zero means either a timeout or no file descriptors to + // wait for. Try timeout on first occurrence, then assume no file + // descriptors, which means wait for 100 milliseconds to prevent spinning + // in Perform + Wait. + if numFds == 0 { + repeats++ // count number of repeated zero numFds + if repeats > 1 { + time.Sleep(100 * time.Millisecond) + } + } else { + repeats = 0 + } + } +} diff --git a/multi.go b/multi.go index 5794717..ddac979 100644 --- a/multi.go +++ b/multi.go @@ -94,6 +94,14 @@ func (mcurl *CURLM) Perform() (int, error) { return int(running_handles), err } +// curl_multi_wait - polls on all easy handles in a multi handle +func (mcurl *CURLM) Wait(timeoutMs int) (int, error) { + p := mcurl.handle + handles_with_events := C.int(0) + err := newCurlMultiError(C.curl_multi_wait(p, nil, 0, C.int(timeoutMs), &handles_with_events)) + return int(handles_with_events), err +} + // curl_multi_add_handle - add an easy handle to a multi session func (mcurl *CURLM) AddHandle(easy *CURL) error { mp := mcurl.handle From 0c332e03c41b39f07b50bf29c472720b8d9b8b72 Mon Sep 17 00:00:00 2001 From: Sorin Otescu Date: Fri, 14 Jun 2019 16:04:57 +0300 Subject: [PATCH 3/3] Add PROTO_* constants --- const_gen.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++-- misc/codegen.py | 16 ++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/const_gen.go b/const_gen.go index 4a9e88c..ae92b4d 100644 --- a/const_gen.go +++ b/const_gen.go @@ -59,7 +59,7 @@ const ( E_UNKNOWN_OPTION = C.CURLE_UNKNOWN_OPTION E_TELNET_OPTION_SYNTAX = C.CURLE_TELNET_OPTION_SYNTAX E_OBSOLETE50 = C.CURLE_OBSOLETE50 - E_PEER_FAILED_VERIFICATION = C.CURLE_PEER_FAILED_VERIFICATION + E_OBSOLETE51 = C.CURLE_OBSOLETE51 E_GOT_NOTHING = C.CURLE_GOT_NOTHING E_SSL_ENGINE_NOTFOUND = C.CURLE_SSL_ENGINE_NOTFOUND E_SSL_ENGINE_SETFAILED = C.CURLE_SSL_ENGINE_SETFAILED @@ -68,7 +68,7 @@ const ( E_OBSOLETE57 = C.CURLE_OBSOLETE57 E_SSL_CERTPROBLEM = C.CURLE_SSL_CERTPROBLEM E_SSL_CIPHER = C.CURLE_SSL_CIPHER - E_SSL_CACERT = C.CURLE_SSL_CACERT + E_PEER_FAILED_VERIFICATION = C.CURLE_PEER_FAILED_VERIFICATION E_BAD_CONTENT_ENCODING = C.CURLE_BAD_CONTENT_ENCODING E_LDAP_INVALID_URL = C.CURLE_LDAP_INVALID_URL E_FILESIZE_EXCEEDED = C.CURLE_FILESIZE_EXCEEDED @@ -101,10 +101,12 @@ const ( E_SSL_PINNEDPUBKEYNOTMATCH = C.CURLE_SSL_PINNEDPUBKEYNOTMATCH E_SSL_INVALIDCERTSTATUS = C.CURLE_SSL_INVALIDCERTSTATUS E_HTTP2_STREAM = C.CURLE_HTTP2_STREAM + E_RECURSIVE_API_CALL = C.CURLE_RECURSIVE_API_CALL E_OBSOLETE16 = C.CURLE_OBSOLETE16 E_OBSOLETE10 = C.CURLE_OBSOLETE10 E_OBSOLETE12 = C.CURLE_OBSOLETE12 E_FTP_WEIRD_SERVER_REPLY = C.CURLE_FTP_WEIRD_SERVER_REPLY + E_SSL_CACERT = C.CURLE_SSL_CACERT E_UNKNOWN_TELNET_OPTION = C.CURLE_UNKNOWN_TELNET_OPTION E_SSL_PEER_CERTIFICATE = C.CURLE_SSL_PEER_CERTIFICATE E_OBSOLETE = C.CURLE_OBSOLETE @@ -397,6 +399,25 @@ const ( OPT_SOCKS5_AUTH = C.CURLOPT_SOCKS5_AUTH OPT_SSH_COMPRESSION = C.CURLOPT_SSH_COMPRESSION OPT_MIMEPOST = C.CURLOPT_MIMEPOST + OPT_TIMEVALUE_LARGE = C.CURLOPT_TIMEVALUE_LARGE + OPT_HAPPY_EYEBALLS_TIMEOUT_MS = C.CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS + OPT_RESOLVER_START_FUNCTION = C.CURLOPT_RESOLVER_START_FUNCTION + OPT_RESOLVER_START_DATA = C.CURLOPT_RESOLVER_START_DATA + OPT_HAPROXYPROTOCOL = C.CURLOPT_HAPROXYPROTOCOL + OPT_DNS_SHUFFLE_ADDRESSES = C.CURLOPT_DNS_SHUFFLE_ADDRESSES + OPT_TLS13_CIPHERS = C.CURLOPT_TLS13_CIPHERS + OPT_PROXY_TLS13_CIPHERS = C.CURLOPT_PROXY_TLS13_CIPHERS + OPT_DISALLOW_USERNAME_IN_URL = C.CURLOPT_DISALLOW_USERNAME_IN_URL + OPT_DOH_URL = C.CURLOPT_DOH_URL + OPT_UPLOAD_BUFFERSIZE = C.CURLOPT_UPLOAD_BUFFERSIZE + OPT_UPKEEP_INTERVAL_MS = C.CURLOPT_UPKEEP_INTERVAL_MS + OPT_CURLU = C.CURLOPT_CURLU + OPT_TRAILERFUNCTION = C.CURLOPT_TRAILERFUNCTION + OPT_TRAILERDATA = C.CURLOPT_TRAILERDATA + OPT_HTTP09_ALLOWED = C.CURLOPT_HTTP09_ALLOWED + OPT_ALTSVC_CTRL = C.CURLOPT_ALTSVC_CTRL + OPT_ALTSVC = C.CURLOPT_ALTSVC + OPT_MAXAGE_CONN = C.CURLOPT_MAXAGE_CONN OPT_POST301 = C.CURLOPT_POST301 OPT_SSLKEYPASSWD = C.CURLOPT_SSLKEYPASSWD OPT_FTPAPPEND = C.CURLOPT_FTPAPPEND @@ -428,6 +449,7 @@ const ( INFO_REQUEST_SIZE = C.CURLINFO_REQUEST_SIZE INFO_SSL_VERIFYRESULT = C.CURLINFO_SSL_VERIFYRESULT INFO_FILETIME = C.CURLINFO_FILETIME + INFO_FILETIME_T = C.CURLINFO_FILETIME_T INFO_CONTENT_LENGTH_DOWNLOAD = C.CURLINFO_CONTENT_LENGTH_DOWNLOAD INFO_CONTENT_LENGTH_DOWNLOAD_T = C.CURLINFO_CONTENT_LENGTH_DOWNLOAD_T INFO_CONTENT_LENGTH_UPLOAD = C.CURLINFO_CONTENT_LENGTH_UPLOAD @@ -465,6 +487,13 @@ const ( INFO_PROXY_SSL_VERIFYRESULT = C.CURLINFO_PROXY_SSL_VERIFYRESULT INFO_PROTOCOL = C.CURLINFO_PROTOCOL INFO_SCHEME = C.CURLINFO_SCHEME + INFO_TOTAL_TIME_T = C.CURLINFO_TOTAL_TIME_T + INFO_NAMELOOKUP_TIME_T = C.CURLINFO_NAMELOOKUP_TIME_T + INFO_CONNECT_TIME_T = C.CURLINFO_CONNECT_TIME_T + INFO_PRETRANSFER_TIME_T = C.CURLINFO_PRETRANSFER_TIME_T + INFO_STARTTRANSFER_TIME_T = C.CURLINFO_STARTTRANSFER_TIME_T + INFO_REDIRECT_TIME_T = C.CURLINFO_REDIRECT_TIME_T + INFO_APPCONNECT_TIME_T = C.CURLINFO_APPCONNECT_TIME_T INFO_LASTONE = C.CURLINFO_LASTONE INFO_HTTP_CODE = C.CURLINFO_HTTP_CODE ) @@ -480,9 +509,43 @@ const ( AUTH_NTLM = C.CURLAUTH_NTLM & (1<<32 - 1) AUTH_DIGEST_IE = C.CURLAUTH_DIGEST_IE & (1<<32 - 1) AUTH_NTLM_WB = C.CURLAUTH_NTLM_WB & (1<<32 - 1) + AUTH_BEARER = C.CURLAUTH_BEARER & (1<<32 - 1) AUTH_ONLY = C.CURLAUTH_ONLY & (1<<32 - 1) AUTH_ANY = C.CURLAUTH_ANY & (1<<32 - 1) AUTH_ANYSAFE = C.CURLAUTH_ANYSAFE & (1<<32 - 1) ) +// Proto +const ( + PROTO_HTTP = C.CURLPROTO_HTTP & (1<<32 - 1) + PROTO_HTTPS = C.CURLPROTO_HTTPS & (1<<32 - 1) + PROTO_FTP = C.CURLPROTO_FTP & (1<<32 - 1) + PROTO_FTPS = C.CURLPROTO_FTPS & (1<<32 - 1) + PROTO_SCP = C.CURLPROTO_SCP & (1<<32 - 1) + PROTO_SFTP = C.CURLPROTO_SFTP & (1<<32 - 1) + PROTO_TELNET = C.CURLPROTO_TELNET & (1<<32 - 1) + PROTO_LDAP = C.CURLPROTO_LDAP & (1<<32 - 1) + PROTO_LDAPS = C.CURLPROTO_LDAPS & (1<<32 - 1) + PROTO_DICT = C.CURLPROTO_DICT & (1<<32 - 1) + PROTO_FILE = C.CURLPROTO_FILE & (1<<32 - 1) + PROTO_TFTP = C.CURLPROTO_TFTP & (1<<32 - 1) + PROTO_IMAP = C.CURLPROTO_IMAP & (1<<32 - 1) + PROTO_IMAPS = C.CURLPROTO_IMAPS & (1<<32 - 1) + PROTO_POP3 = C.CURLPROTO_POP3 & (1<<32 - 1) + PROTO_POP3S = C.CURLPROTO_POP3S & (1<<32 - 1) + PROTO_SMTP = C.CURLPROTO_SMTP & (1<<32 - 1) + PROTO_SMTPS = C.CURLPROTO_SMTPS & (1<<32 - 1) + PROTO_RTSP = C.CURLPROTO_RTSP & (1<<32 - 1) + PROTO_RTMP = C.CURLPROTO_RTMP & (1<<32 - 1) + PROTO_RTMPT = C.CURLPROTO_RTMPT & (1<<32 - 1) + PROTO_RTMPE = C.CURLPROTO_RTMPE & (1<<32 - 1) + PROTO_RTMPTE = C.CURLPROTO_RTMPTE & (1<<32 - 1) + PROTO_RTMPS = C.CURLPROTO_RTMPS & (1<<32 - 1) + PROTO_RTMPTS = C.CURLPROTO_RTMPTS & (1<<32 - 1) + PROTO_GOPHER = C.CURLPROTO_GOPHER & (1<<32 - 1) + PROTO_SMB = C.CURLPROTO_SMB & (1<<32 - 1) + PROTO_SMBS = C.CURLPROTO_SMBS & (1<<32 - 1) + PROTO_ALL = C.CURLPROTO_ALL & (1<<32 - 1) +) + // generated ends diff --git a/misc/codegen.py b/misc/codegen.py index 050f826..1afd187 100644 --- a/misc/codegen.py +++ b/misc/codegen.py @@ -26,6 +26,7 @@ def get_curl_path(): codes = [] infos = [] auths = [] +protos = [] init_pattern = re.compile(r'CINIT\((.*?),\s+(LONG|OBJECTPOINT|FUNCTIONPOINT|STRINGPOINT|OFF_T),\s+(\d+)\)') error_pattern = re.compile('^\s+(CURLE_[A-Z_0-9]+),') info_pattern = re.compile('^\s+(CURLINFO_[A-Z_0-9]+)\s+=') @@ -43,6 +44,10 @@ def get_curl_path(): o = line.split() auths.append(o[1][9:]) + if line.startswith('#define CURLPROTO_'): + o = line.split() + protos.append(o[1][10:]) + match = error_pattern.findall(line) if match: codes.append(match[0]) @@ -89,6 +94,11 @@ def get_curl_path(): {auth_part} ) +// Proto +const ( +{proto_part} +) + // generated ends """ @@ -116,5 +126,11 @@ def get_curl_path(): auth_part = '\n'.join(auth_part) +proto_part = [] +for p in protos: + proto_part.append("\tPROTO_{0:<25} = C.CURLPROTO_{0} & (1<<32 - 1)".format(p)) + +proto_part = '\n'.join(proto_part) + with open('./const_gen.go', 'w') as fp: fp.write(template.format(**locals()))