Hi!
I'm actually building an automation tool based on Selenium with Go called 
IGopher and I have had a few requests to implement native proxy support.  
However, I am facing an issue with those with authentication...  
I can't send the proxy credentials to Chrome and without them it asks 
through an alert box for authentication that I can hardly interact with 
through Selenium (I'm not even sure it's possible in headless mode) .

So I thought of an intermediary proxy system hosted locally by my program 
which will add the *Proxy-Authorization* header and transfer the request to 
the remote proxy:

[image: IGopher_proxies.jpg]

Something like this:  proxy-login-automator 
<https://github.com/sjitech/proxy-login-automator>

I'm not very familiar with proxies to be honest, but I tried this approach 
using *NewSingleHostReverseProxy*: 
```go
var (
localServerHost  string
remoteServerHost string
remoteServerAuth string
)

// ProxyConfig store all remote proxy configuration
type ProxyConfig struct {
IP       string `yaml:"ip"`
Port     int    `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Enabled  bool   `yaml:"activated"`
}

func PrintResponse(r *http.Response) error {
logrus.Infof("Response: %+v\n", r)
return nil
}

// LaunchForwardingProxy launch forward server used to inject proxy 
authentication header
// into outgoing requests
func LaunchForwardingProxy(localPort uint16, remoteProxy ProxyConfig) error 
{
localServerHost = fmt.Sprintf("localhost:%d", localPort)
remoteServerHost = fmt.Sprintf(
"http://%s:%d";,
remoteProxy.IP,
remoteProxy.Port,
)
remoteServerAuth = fmt.Sprintf(
"%s:%s",
remoteProxy.Username,
remoteProxy.Password,
)

remote, err := url.Parse(remoteServerHost)
if err != nil {
panic(err)
}

proxy := httputil.NewSingleHostReverseProxy(remote)
d := func(req *http.Request) {
logrus.Infof("Pre-Edited request: %+v\n", req)
// Inject proxy authentication headers to outgoing request into new Header
basicAuth := "Basic " + 
base64.StdEncoding.EncodeToString([]byte(remoteServerAuth))
req.Header.Set("Proxy-Authorization", basicAuth)
logrus.Infof("Edited Request: %+v\n", req)
logrus.Infof("Scheme: %s, Host: %s, Port: %s\n", req.URL.Scheme, 
req.URL.Host, req.URL.Port())
}
proxy.Director = d
proxy.ModifyResponse = PrintResponse
http.ListenAndServe(localServerHost, proxy)

return nil
}
```

With this code snippet, I'm able to intercept the request and update the 
header. 
However, resending the CONNECT request fails with the following output:

```
INFO[0028] Pre-Edited request: &{Method:CONNECT URL://google.com:443 
Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 
Header:map[Proxy-Connection:[Keep-Alive] User-Agent:[curl/7.68.0]] 
Body:<nil> GetBody:<nil> ContentLength:0 TransferEncoding:[] Close:false 
Host:google.com:443 Form:map[] PostForm:map[] MultipartForm:<nil> 
Trailer:map[] RemoteAddr:127.0.0.1:35610 RequestURI:google.com:443 
TLS:<nil> Cancel:<nil> Response:<nil> ctx:0xc000164300}  function=func1 
line=59

INFO[0028] Edited Request: &{Method:CONNECT URL://google.com:443 
Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 
Header:map[Proxy-Authorization:[Basic <auth>] Proxy-Connection:[Keep-Alive] 
User-Agent:[curl/7.68.0]] Body:<nil> GetBody:<nil> ContentLength:0 
TransferEncoding:[] Close:false Host:google.com:443 Form:map[] 
PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr:127.0.0.1:35610 
RequestURI:google.com:443 TLS:<nil> Cancel:<nil> Response:<nil> 
ctx:0xc000164300}  function=func1 line=63

INFO[0028] Scheme: , Host: google.com:443, Port: 443     function=func1 
line=64

*2021/03/15 21:35:11 http: proxy error: unsupported protocol scheme ""*
```

What am I doing wrong? Is there a way to send a CONNECT request without 
scheme in Go?
Maybe I'm doing something wrong or my approach to this problem is wrong. 
Are there better methods to achieve my goals?

If you have an idea to complete what I did or any other method, please let 
me know! :)

You can find all IGopher sources here: GitHub repository 
<https://github.com/hbollon/IGopher> (Proxy stuff excluded)

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ededf8bc-f42d-4ee1-bad4-4ef690549f8dn%40googlegroups.com.

Reply via email to