Exemplo n.º 1
0
func (easy *Easy) SetOpt(opt EasyOption, param interface{}) error {
	switch {
	case opt >= C.CURLOPTTYPE_OFF_T:
		return easy.getError(C.my_esetoptl(easy.cptr, C.CURLoption(opt), C.long(param.(int))))
	case opt >= C.CURLOPTTYPE_FUNCTIONPOINT:
		return errors.New("function options not supported by SetOpt()")
	case opt >= C.CURLOPTTYPE_OBJECTPOINT:
		if isStringOption(opt) {
			c_param := C.CString(param.(string))
			defer C.free(unsafe.Pointer(c_param))
			return easy.getError(C.my_esetoptc(easy.cptr, C.CURLoption(opt), c_param))
		} else {
			return fmt.Errorf("option %d not supported", opt)
		}
	case opt >= C.CURLOPTTYPE_LONG:
		var val C.long
		switch t := param.(type) {
		case bool:
			if t {
				val = C.long(1)
			}
		case int:
			val = C.long(t)
		case int32:
			val = C.long(t)
		case int64:
			val = C.long(t)
		default:
			panic("CURLOPTTYPE_LONG param must be of golang type bool, int, int32, or int64")
		}
		return easy.getError(C.my_esetoptl(easy.cptr, C.CURLoption(opt), val))
	}
	return nil
}
Exemplo n.º 2
0
Arquivo: easy.go Projeto: ym/go-curl
// curl_easy_setopt - set options for a curl easy handle
// WARNING: a function pointer is &fun, but function addr is reflect.ValueOf(fun).Pointer()
func (curl *CURL) Setopt(opt int, param interface{}) error {
	p := curl.handle
	if param == nil {
		// NOTE: some option will crash program when got a nil param
		return newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt), nil))
	}
	switch {
	// not really set
	case opt == OPT_READDATA: // OPT_INFILE
		curl.readData = &param
		return nil
	case opt == OPT_DEBUGDATA:
		curl.debugData = &param
		return nil
	case opt == OPT_PROGRESSDATA:
		curl.progressData = &param
		return nil
	case opt == OPT_HEADERDATA: // also known as OPT_WRITEHEADER
		curl.headerData = &param
		return nil
	case opt == OPT_WRITEDATA: // OPT_FILE
		curl.writeData = &param
		return nil

	case opt == OPT_READFUNCTION:
		fun := param.(func([]byte, interface{}) int)
		curl.readFunction = &fun

		ptr := C.return_read_function()
		if err := newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt), ptr)); err == nil {
			return newCurlError(C.curl_easy_setopt_pointer(p, OPT_READDATA,
				unsafe.Pointer(reflect.ValueOf(curl).Pointer())))
		} else {
			return err
		}

	case opt == OPT_PROGRESSFUNCTION:
		fun := param.(func(float64, float64, float64, float64, interface{}) bool)
		curl.progressFunction = &fun

		ptr := C.return_progress_function()
		if err := newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt), ptr)); err == nil {
			return newCurlError(C.curl_easy_setopt_pointer(p, OPT_PROGRESSDATA,
				unsafe.Pointer(reflect.ValueOf(curl).Pointer())))
		} else {
			return err
		}

	case opt == OPT_DEBUGFUNCTION:
		fun := param.(func(int, []byte) bool)
		curl.debugFunction = &fun

		ptr := C.return_debug_function()
		if err := newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt), ptr)); err == nil {
			return newCurlError(C.curl_easy_setopt_pointer(p, OPT_DEBUGDATA,
				unsafe.Pointer(reflect.ValueOf(curl).Pointer())))
		} else {
			return err
		}

	case opt == OPT_HEADERFUNCTION:
		fun := param.(func([]byte, interface{}) bool)
		curl.headerFunction = &fun

		ptr := C.return_header_function()
		if err := newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt), ptr)); err == nil {
			return newCurlError(C.curl_easy_setopt_pointer(p, OPT_HEADERDATA,
				unsafe.Pointer(reflect.ValueOf(curl).Pointer())))
		} else {
			return err
		}

	case opt == OPT_WRITEFUNCTION:
		fun := param.(func([]byte, interface{}) bool)
		curl.writeFunction = &fun

		ptr := C.return_write_function()
		if err := newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt), ptr)); err == nil {
			return newCurlError(C.curl_easy_setopt_pointer(p, OPT_WRITEDATA,
				unsafe.Pointer(reflect.ValueOf(curl).Pointer())))
		} else {
			return err
		}

	// for OPT_HTTPPOST, use struct Form
	case opt == OPT_HTTPPOST:
		post := param.(*Form)
		ptr := post.head
		return newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt), unsafe.Pointer(ptr)))

	case opt >= C.CURLOPTTYPE_OFF_T:
		val := C.off_t(0)
		switch t := param.(type) {
		case int:
			val = C.off_t(t)
		case uint64:
			val = C.off_t(t)
		default:
			panic("OFF_T conversion not supported")
		}
		return newCurlError(C.curl_easy_setopt_off_t(p, C.CURLoption(opt), val))

	case opt >= C.CURLOPTTYPE_FUNCTIONPOINT:
		// function pointer
		panic("function pointer not implemented yet!")

	case opt >= C.CURLOPTTYPE_OBJECTPOINT:
		switch t := param.(type) {
		case string:
			ptr := C.CString(t)
			curl.mallocAddPtr(ptr)
			return newCurlError(C.curl_easy_setopt_string(p, C.CURLoption(opt), ptr))
		case CurlString:
			ptr := (*C.char)(t)
			return newCurlError(C.curl_easy_setopt_string(p, C.CURLoption(opt), ptr))
		case []string:
			if len(t) > 0 {
				ptr := C.CString(t[0])
				curl.mallocAddPtr(ptr)
				a_slist := C.curl_slist_append(nil, ptr)
				for _, s := range t[1:] {
					ptr := C.CString(s)
					curl.mallocAddPtr(ptr)
					a_slist = C.curl_slist_append(a_slist, ptr)
				}
				return newCurlError(C.curl_easy_setopt_slist(p, C.CURLoption(opt), a_slist))
			} else {
				return newCurlError(C.curl_easy_setopt_slist(p, C.CURLoption(opt), nil))
			}
		case []CurlString:
			if len(t) > 0 {
				ptr := (*C.char)(t[0])
				a_slist := C.curl_slist_append(nil, ptr)
				for _, s := range t[1:] {
					ptr := (*C.char)(s)
					a_slist = C.curl_slist_append(a_slist, ptr)
				}
				return newCurlError(C.curl_easy_setopt_slist(p, C.CURLoption(opt), a_slist))
			} else {
				return newCurlError(C.curl_easy_setopt_slist(p, C.CURLoption(opt), nil))
			}
		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)
			// pass a pointer to GoInterface
			return newCurlError(C.curl_easy_setopt_pointer(p, C.CURLoption(opt),
				unsafe.Pointer(&param)))
		}
	case opt >= C.CURLOPTTYPE_LONG:
		val := C.long(0)
		switch t := param.(type) {
		case int:
			val = C.long(t)
		case bool:
			if t {
				val = 1
			}
		case int64:
			val = C.long(t)
		case int32:
			val = C.long(t)
		default:
			panic("not supported converstion to c long")
		}
		return newCurlError(C.curl_easy_setopt_long(p, C.CURLoption(opt), val))
	}
	panic("opt param error!")
}