elazarl / goproxy

An HTTP proxy library for Go
BSD 3-Clause "New" or "Revised" License
5.98k stars 1.09k forks source link

Panic: mutateHeaderFunc not supported in modified Transport while using basic auth in transport proxy #220

Open wturyn opened 7 years ago

wturyn commented 7 years ago

Example below demonstrates issue i have with dynamically set proxy. If i use addr1 - that is proxy without basic auth - everything works as expected. On the other hand if i use addr0 i get following exception:

http: panic serving 127.0.0.1:38870: mutateHeaderFunc not supported in modified Transport
goroutine 19 [running]:
net/http.(*conn).serve.func1(0xc4200b1180)
    /home/wt/Apps/go1.8/go/src/net/http/server.go:1721 +0xd0
panic(0x67db80, 0xc420116ae0)
    /home/wt/Apps/go1.8/go/src/runtime/panic.go:489 +0x2cf
github.com/elazarl/goproxy/transport.(*persistConn).roundTrip(0xc420078700, 0xc420053ab0, 0xc420078700, 0x0, 0x0)
    /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/transport/transport.go:657 +0x430
github.com/elazarl/goproxy/transport.(*Transport).DetailedRoundTrip(0xc420092a40, 0xc4200f2300, 0xc420053b08, 0x5f153f, 0xc42007f980, 0x6e3d3a)
    /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/transport/transport.go:169 +0x30e
main.main.func1.1(0xc4200f2300, 0xc4200a6e60, 0x6e3d3a, 0xa, 0xc420053b58)
    /home/wt/Projects/GoWorkspace/src/bitbucket.org/wturyn/prokurilo/main.go:23 +0x34
github.com/elazarl/goproxy.RoundTripperFunc.RoundTrip(0xc420116a40, 0xc4200f2300, 0xc4200a6e60, 0xc420116a50, 0x67db80, 0xc420116a60)
    /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/ctx.go:33 +0x3a
github.com/elazarl/goproxy.(*ProxyCtx).RoundTrip(0xc4200a6e60, 0xc4200f2300, 0xc4200a6e60, 0xc4200f2300, 0x0)
    /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/ctx.go:38 +0x4c
github.com/elazarl/goproxy.(*ProxyHttpServer).ServeHTTP(0xc420078500, 0x80a540, 0xc4201141c0, 0xc4200f2300)
    /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/proxy.go:112 +0x74e
net/http.serverHandler.ServeHTTP(0xc4200be6e0, 0x80a540, 0xc4201141c0, 0xc4200f2300)
    /home/wt/Apps/go1.8/go/src/net/http/server.go:2568 +0x92
net/http.(*conn).serve(0xc4200b1180, 0x80aa40, 0xc420092740)
    /home/wt/Apps/go1.8/go/src/net/http/server.go:1825 +0x612
created by net/http.(*Server).Serve
    /home/wt/Apps/go1.8/go/src/net/http/server.go:2668 +0x2ce

Example:

package main

import (
    "net/http"
    "log"
    "github.com/elazarl/goproxy"
    "github.com/elazarl/goproxy/transport"
    "net/url"
)

func main() {
    pr := goproxy.NewProxyHttpServer()
    pr.Verbose = true

    pr.OnRequest().DoFunc(func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
        const addr0 = "http://aaa:bbb@117.135.198.33:8088"
        const addr1 = "http://117.135.198.33:8088"

        proxyURL, _ := url.Parse(addr0)
        tr := transport.Transport{Proxy: transport.ProxyURL(proxyURL)}

        ctx.RoundTripper = goproxy.RoundTripperFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (resp *http.Response, err error) {
            _, resp, err = tr.DetailedRoundTrip(req)
            return
        })

        return r, nil
    })
    log.Fatal(http.ListenAndServe(":8000", pr))
}
elazarl commented 7 years ago

I'll look into that, but I have to be honest, this can take a few months, I unfortunately don't have much time for this project these days.

Many thanks for the great bug report.

On Tue, May 2, 2017, 1:16 AM Wojciech Turyn notifications@github.com wrote:

Example below demonstrates issue i have with dynamically set proxy. If i use addr1 - that is proxy without basic auth - everything works as expected. On the other hand if i use addr0 i get following exception:

http: panic serving 127.0.0.1:38870: mutateHeaderFunc not supported in modified Transport goroutine 19 [running]: net/http.(conn).serve.func1(0xc4200b1180) /home/wt/Apps/go1.8/go/src/net/http/server.go:1721 +0xd0 panic(0x67db80, 0xc420116ae0) /home/wt/Apps/go1.8/go/src/runtime/panic.go:489 +0x2cfgithub.com/elazarl/goproxy/transport.(persistConn).roundTrip(0xc420078700, 0xc420053ab0, 0xc420078700, 0x0, 0x0) /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/transport/transport.go:657 +0x430github.com/elazarl/goproxy/transport.(Transport).DetailedRoundTrip(0xc420092a40, 0xc4200f2300, 0xc420053b08, 0x5f153f, 0xc42007f980, 0x6e3d3a) /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/transport/transport.go:169 +0x30e main.main.func1.1(0xc4200f2300, 0xc4200a6e60, 0x6e3d3a, 0xa, 0xc420053b58) /home/wt/Projects/GoWorkspace/src/bitbucket.org/wturyn/prokurilo/main.go:23 +0x34github.com/elazarl/goproxy.RoundTripperFunc.RoundTrip(0xc420116a40, 0xc4200f2300, 0xc4200a6e60, 0xc420116a50, 0x67db80, 0xc420116a60) /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/ctx.go:33 +0x3agithub.com/elazarl/goproxy.(ProxyCtx).RoundTrip(0xc4200a6e60, 0xc4200f2300, 0xc4200a6e60, 0xc4200f2300, 0x0) /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/ctx.go:38 +0x4cgithub.com/elazarl/goproxy.(ProxyHttpServer).ServeHTTP(0xc420078500, 0x80a540, 0xc4201141c0, 0xc4200f2300) /home/wt/Projects/GoWorkspace/src/github.com/elazarl/goproxy/proxy.go:112 +0x74e net/http.serverHandler.ServeHTTP(0xc4200be6e0, 0x80a540, 0xc4201141c0, 0xc4200f2300) /home/wt/Apps/go1.8/go/src/net/http/server.go:2568 +0x92 net/http.(conn).serve(0xc4200b1180, 0x80aa40, 0xc420092740) /home/wt/Apps/go1.8/go/src/net/http/server.go:1825 +0x612 created by net/http.(*Server).Serve /home/wt/Apps/go1.8/go/src/net/http/server.go:2668 +0x2ce

Example:

package main import ( "net/http" "log" "github.com/elazarl/goproxy" "github.com/elazarl/goproxy/transport" "net/url" ) func main() { pr := goproxy.NewProxyHttpServer() pr.Verbose = true

pr.OnRequest().DoFunc(func(r http.Request, ctx goproxy.ProxyCtx) (http.Request, http.Response) { const addr0 = "http://aaa:bbb@117.135.198.33:8088" const addr1 = "http://117.135.198.33:8088"

  proxyURL, _ := url.Parse(addr0)
  tr := transport.Transport{Proxy: transport.ProxyURL(proxyURL)}

  ctx.RoundTripper = goproxy.RoundTripperFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (resp *http.Response, err error) {
      _, resp, err = tr.DetailedRoundTrip(req)
      return
  })

  return r, nil

}) log.Fatal(http.ListenAndServe(":8000", pr)) }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/elazarl/goproxy/issues/220, or mute the thread https://github.com/notifications/unsubscribe-auth/AAP4ojbHfm36-1WUz3x73i3SSBxhlekUks5r1lmsgaJpZM4NNgAn .

wturyn commented 7 years ago

I've looked at your code and obviously the reason for the panic is here: https://github.com/elazarl/goproxy/blob/master/transport/transport.go#L657 I imagine that you put it there because extraHeaders are actually never written.

Neither http.Request.Write nor http.Request.WriteProxy allow to write extra headers.

In standard library all those structs are in the same package (http) and thus have access to unexported method http.Request.write (for example here: https://github.com/golang/go/blob/master/src/net/http/transport.go#L1754)

Unfortunately, the only solution for my specific purpose is to mutate the original request and set those headers inside RoundTripperFunc.

elazarl commented 7 years ago

Are you using the latest commit? IIRC transport is no longer used.

On Wed, May 3, 2017, 5:05 PM Wojciech Turyn notifications@github.com wrote:

I've looked at your code and obviously the reason for the panic is here: https://github.com/elazarl/goproxy/blob/master/transport/transport.go#L657 I imagine that you put it there because extraHeaders are actually never written.

Neither http.Request.Write nor http.Request.WriteProxy allow to write extra headers.

In standard library all those structs are in the same package (http) and thus have access to unexported method http.Request.write (for example here: https://github.com/golang/go/blob/master/src/net/http/transport.go#L1754)

Unfortunately, the only solution for my specific purpose is to mutate the original request and set those headers inside RoundTripperFunc.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/elazarl/goproxy/issues/220#issuecomment-298921006, or mute the thread https://github.com/notifications/unsubscribe-auth/AAP4ovgxjBIFg1JpklLeww0Ikdye77zdks5r2InAgaJpZM4NNgAn .

wturyn commented 7 years ago

Which commit do you refer to?

fcce commented 4 years ago

the same problem