I solved my problem. The offending line what in the request.go file for the net/http package:
558 host := cleanHost(r.Host) 559 if host == "" { 560 if r.URL == nil { 561 return errMissingHost 562 } 563 host = cleanHost(r.URL.Host) 564 } ... 571 ruri := r.URL.RequestURI() 572 if usingProxy && r.URL.Scheme != "" && r.URL.Opaque == "" { 573 ruri = r.URL.Scheme + "://" + host + ruri The host used is the one from the header if it is found. I bypass it setting the r.URL.Opaque: 103 if p, err := proxy(req); p != nil && err == nil && req.URL.Scheme == "http" { 104 req.URL.Opaque = fmt.Sprintf("%s://%s", req.URL.Scheme, path.Join(req.URL.Host, req.URL.Path)) 105 } I'm pretty sure I'm not catching a ton of corner cases but IMHO I think it should use r.URL.Host first like the doc says for the basic request. On Mon, Jan 27, 2020 at 11:22 AM Edouard Buschini < edouard.busch...@gmail.com> wrote: > Hi all! > > Asking for the help of the community because I haven't been able to find > the answer on my own. > > I'm writing an http fuzzer in go and was implementing a proxy options from > the cli. > My use case is that I want all the requests to be sent to the proxy when > the flag is set. No matter if it's tls or just pure http. > > For this, I just the `Proxy` field in the `http.Transport` type. It works > well for TLS because it first sends the CONNECT method and then request is > just written to the socket when the TLS handshake has been established. > But for not TLS, it actually does not use CONNECT, instead, it changes the > `URL` field of the `http.Request` object to the `Host` field. So when the > request arrives to the proxy, the request is all messed up if the initial > `Host` field did not actually contain a reachable host. > > I've tried sending the full proxied request using `CONNECT > <host>:80\r\n\r\n` with netcat and it worked: > > ``` > > CONNECT www.google.com:80 HTTP/1.1 > > > HTTP/1.0 200 Connection established > > > POST / HTTP/1.1 > > Host: 2 > > User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 > Firefox/68.0 > > > > HTTP/1.1 204 No Content > > ... > > ``` > > > What I'm doing right now is: > > ``` > > var proxy func(*http.Request) (*url.URL, error) > > proxy = http.ProxyFromEnvironment > > > if flags.Proxy != nil { > > proxy = http.ProxyURL(flags.Proxy) > > } > > > numRedirects := 0 > > client := http.Client{ > > Transport: &http.Transport{ > > Proxy: proxy, > > TLSClientConfig: &tls.Config{ > > InsecureSkipVerify: flags.Insecure, > > }, > > }, > > } > ``` > > I've looked at the code a little bit and found that: > https://golang.org/src/net/http/transport.go#L1516 is where it happens. > And I can clearly see that `CONNECT` is used when it needs to setup a TLS > tunnel. > > If you guys have any idea how to achieve this, that would be awesome! > Right now, I'm thinking just using `req.Write` after creating the > connection myself, but I kind of don't really want to re-invent the wheel > knowing that `http.Client` is great. > > Thank you!! > > > -- > 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/2c2ae451-87d4-4d96-a68f-572b152cb9af%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/2c2ae451-87d4-4d96-a68f-572b152cb9af%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- 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/CADTiKyyHG%3D9Txagv6Kjj-f19j49Z8ckDsz9Z%2B_6HkJN3FtdJxw%40mail.gmail.com.