1package ieproxy
2
3import (
4	"strings"
5	"syscall"
6	"unsafe"
7)
8
9func (psc *ProxyScriptConf) findProxyForURL(URL string) string {
10	if !psc.Active {
11		return ""
12	}
13	proxy, _ := getProxyForURL(psc.PreConfiguredURL, URL)
14	i := strings.Index(proxy, ";")
15	if i >= 0 {
16		return proxy[:i]
17	}
18	return proxy
19}
20
21func getProxyForURL(pacfileURL, URL string) (string, error) {
22	pacfileURLPtr, err := syscall.UTF16PtrFromString(pacfileURL)
23	if err != nil {
24		return "", err
25	}
26	URLPtr, err := syscall.UTF16PtrFromString(URL)
27	if err != nil {
28		return "", err
29	}
30
31	handle, _, err := winHttpOpen.Call(0, 0, 0, 0, 0)
32	if handle == 0 {
33		return "", err
34	}
35	defer winHttpCloseHandle.Call(handle)
36
37	dwFlags := fWINHTTP_AUTOPROXY_CONFIG_URL
38	dwAutoDetectFlags := autoDetectFlag(0)
39	pfURLptr := pacfileURLPtr
40
41	if pacfileURL == "" {
42		dwFlags = fWINHTTP_AUTOPROXY_AUTO_DETECT
43		dwAutoDetectFlags = fWINHTTP_AUTO_DETECT_TYPE_DNS_A | fWINHTTP_AUTO_DETECT_TYPE_DHCP
44		pfURLptr = nil
45	}
46
47	options := tWINHTTP_AUTOPROXY_OPTIONS{
48		dwFlags:                dwFlags, // adding cache might cause issues: https://github.com/mattn/go-ieproxy/issues/6
49		dwAutoDetectFlags:      dwAutoDetectFlags,
50		lpszAutoConfigUrl:      pfURLptr,
51		lpvReserved:            nil,
52		dwReserved:             0,
53		fAutoLogonIfChallenged: true, // may not be optimal https://msdn.microsoft.com/en-us/library/windows/desktop/aa383153(v=vs.85).aspx
54	} // lpszProxyBypass isn't used as this only executes in cases where there (may) be a pac file (autodetect can fail), where lpszProxyBypass couldn't be returned.
55	// in the case that autodetect fails and no pre-specified pacfile is present, no proxy is returned.
56
57	info := new(tWINHTTP_PROXY_INFO)
58
59	ret, _, err := winHttpGetProxyForURL.Call(
60		handle,
61		uintptr(unsafe.Pointer(URLPtr)),
62		uintptr(unsafe.Pointer(&options)),
63		uintptr(unsafe.Pointer(info)),
64	)
65	if ret > 0 {
66		err = nil
67	}
68
69	defer globalFreeWrapper(info.lpszProxyBypass)
70	defer globalFreeWrapper(info.lpszProxy)
71	return StringFromUTF16Ptr(info.lpszProxy), err
72}
73