Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix C struct and add 'curl_multi_wait' #69

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 65 additions & 2 deletions const_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
)
Expand All @@ -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
2 changes: 1 addition & 1 deletion easy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
66 changes: 66 additions & 0 deletions examples/multi_and_wait.go
Original file line number Diff line number Diff line change
@@ -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
}
}
}
16 changes: 16 additions & 0 deletions misc/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -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+=')
Expand All @@ -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])
Expand Down Expand Up @@ -89,6 +94,11 @@ def get_curl_path():
{auth_part}
)

// Proto
const (
{proto_part}
)

// generated ends
"""

Expand Down Expand Up @@ -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()))
8 changes: 8 additions & 0 deletions multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down