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

Support certinfo #81

Open
wants to merge 6 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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
*.o
src/_cgo_*
src/_obj/

.idea/
43 changes: 38 additions & 5 deletions easy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ static CURLcode curl_easy_getinfo_double(CURL *curl, CURLINFO info, double *p) {
static CURLcode curl_easy_getinfo_slist(CURL *curl, CURLINFO info, struct curl_slist **p) {
return curl_easy_getinfo(curl, info, p);
}
static CURLcode curl_easy_getinfo_certinfo(CURL *curl, CURLINFO info, struct curl_certinfo **p) {
return curl_easy_getinfo(curl, info, p);
}

static CURLFORMcode curl_formadd_name_content_length(
struct curl_httppost **httppost, struct curl_httppost **last_post, char *name, char *content, int length) {
Expand Down Expand Up @@ -66,8 +69,8 @@ import (
"fmt"
"mime"
"path"
"unsafe"
"sync"
"unsafe"
)

type CurlInfo C.CURLINFO
Expand Down Expand Up @@ -137,7 +140,7 @@ func (c *contextMap) Delete(k uintptr) {
delete(c.items, k)
}

var context_map = &contextMap {
var context_map = &contextMap{
items: make(map[uintptr]*CURL),
}

Expand Down Expand Up @@ -292,8 +295,8 @@ func (curl *CURL) Setopt(opt int, param interface{}) error {
default:
// It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.
// val := reflect.ValueOf(param)
//fmt.Printf("DEBUG(Setopt): param=%x\n", val.Pointer())
//println("DEBUG can addr =", val.Pointer(), "opt=", opt)
// fmt.Printf("DEBUG(Setopt): param=%x\n", val.Pointer())
// println("DEBUG can addr =", val.Pointer(), "opt=", opt)
// pass a pointer to GoInterface
return newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt),
unsafe.Pointer(&param)))
Expand Down Expand Up @@ -384,6 +387,36 @@ func (curl *CURL) Unescape(url string) string {
func (curl *CURL) Getinfo(info CurlInfo) (ret interface{}, err error) {
p := curl.handle
cInfo := C.CURLINFO(info)
if cInfo == C.CURLINFO_CERTINFO {
var certInfo *C.struct_curl_certinfo
err := newCurlError(C.curl_easy_getinfo_certinfo(p, cInfo, &certInfo))
if err != nil {
return nil, err
}
if certInfo == nil {
return nil, fmt.Errorf("nil certinfo")
}

certsCount := C.int(certInfo.num_of_certs)
certs := make([]string, certsCount)

nextCert := (**C.struct_curl_slist)(certInfo.certinfo)
for i := range certs {
certPtr := unsafe.Pointer(uintptr(unsafe.Pointer(nextCert)) + unsafe.Sizeof(nextCert)*uintptr(i))
certSlist := *(**C.struct_curl_slist)(certPtr)

var certData string
for certSlist != nil {
certData += C.GoString(certSlist.data) + "\n"
certSlist = certSlist.next
}

certs[i] = certData
}

return certs, nil
}

switch cInfo & C.CURLINFO_TYPEMASK {
case C.CURLINFO_STRING:
a_string := C.CString("")
Expand All @@ -405,7 +438,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(C.struct_curl_slist)
var a_ptr_slist *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
60 changes: 60 additions & 0 deletions examples/certinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"fmt"
"log"

"github.com/andelf/go-curl"
)

func main() {
const domain = "google.com"

if err := curl.GlobalInit(curl.GLOBAL_ALL); err != nil {
log.Println("failed to init libcurl")
return
}
defer curl.GlobalCleanup()

easy := curl.EasyInit()
defer easy.Cleanup()

if easy == nil {
log.Println("failed to init easy curl")
return
}

url := fmt.Sprintf("https://%s", domain)

easy.Setopt(curl.OPT_URL, url)
easy.Setopt(curl.OPT_SSL_VERIFYPEER, true)
easy.Setopt(curl.OPT_SSL_VERIFYHOST, true)
easy.Setopt(curl.OPT_TIMEOUT, 5)
easy.Setopt(curl.OPT_CERTINFO, true)
easy.Setopt(curl.OPT_NOPROGRESS, true)
easy.Setopt(curl.OPT_NOBODY, true)

if err := easy.Perform(); err != nil {
log.Printf("failed to preform request: %v", err)
return
}

res, err := easy.Getinfo(curl.INFO_CERTINFO)
if err != nil {
log.Printf("failed to get cert info: %v", err)
return
}

info, ok := res.([]string)
if !ok {
log.Printf("unknown cert info result: %T", res)
return
}

fmt.Printf("Fetched %d certificates!\n\n", len(info))
for i, certInfo := range info {
fmt.Printf("Certificate info %d:\n", i)
fmt.Printf("%+v\n", certInfo)
fmt.Println()
}
}