Helper functions
jsmouret opened this issue · 4 comments
Hello,
Nice work :)
How do you plug FindProxyForURL in a workflow?
I'm wondering if you use something like this:
func Handler(req *http.Request) (*url.URL, error) {
conf := GetConf()
if conf.Static.Active {
return http.ProxyFromEnvironment(req)
}
if conf.Automatic.Active {
proxy := conf.Automatic.FindProxyForURL(req.URL.String())
if proxy != "" {
return url.Parse(proxy)
}
}
return nil, nil
}
// Client is a proxy enabled http.Client
var Client = &http.Client{
Transport: &http.Transport{
Proxy: Handler,
},
}
// Get issues a GET to the specified URL using the proxy.
func Get(url string) (*http.Response, error) {
return Client.Get(url)
}
If yes, would it be something interesting to add to the library?
Thank you
@oliverpool could you please handle this issue? (if possible)
@jsmouret you raise a really good point!
Actually writing a Proxy handler is actually quite complex.
I considered at some point copy/pasting the http.ProxyFromEnvironment
function (which actually checks other things and may evolve in the future).
There is also the issue of priority : if a static and an automatic configurations are available, which one should be preferred?
Maybe we could add a ProxyURL(*Request) (*url.URL, error)
method to all configurations (Static
, Automatic
, ProxyConf
) which acts like ProxyFromEnvironment
.
Regarding the priority issue, a new field PreferAutomaticConf
(with default to false
) could solve the issue.
This would also simplify your Handler
We could also propose a change to the http
lib to split http.ProxyFromEnvironment
in two parts (I'm not satisfied of the name of the new function...):
func ProxyFromEnvironment(req *Request) (*url.URL, error) {
var proxy string
if req.URL.Scheme == "https" {
proxy = httpsProxyEnv.Get()
}
if proxy == "" {
proxy = httpProxyEnv.Get()
if proxy != "" && os.Getenv("REQUEST_METHOD") != "" {
return nil, errors.New("net/http: refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy")
}
}
return ProxyRequest(proxy, req)
func ProxyRequest(proxy string, req *Request) (*url.URL, error) {
if proxy == "" {
return nil, nil
}
if !useProxy(canonicalAddr(req.URL)) {
return nil, nil
}
proxyURL, err := url.Parse(proxy)
if err != nil ||
(proxyURL.Scheme != "http" &&
proxyURL.Scheme != "https" &&
proxyURL.Scheme != "socks5") {
// proxy was bogus. Try prepending "http://" to it and
// see if that parses correctly. If not, we fall
// through and complain about the original one.
if proxyURL, err := url.Parse("http://" + proxy); err == nil {
return proxyURL, nil
}
}
if err != nil {
return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
}
return proxyURL, nil
}
Currently adding the ProxyURL(*Request) (*url.URL, error)
(and removing FindProxyForURL
?) has my preference !
What do you think about it?
This has been addressed by #10.
See GetProxyFunc
// Client is a proxy enabled http.Client
var Client = &http.Client{
Transport: &http.Transport{
Proxy: ieproxy.GetProxyFunc(),
},
}
Awesome :)