Skip to content

Commit

Permalink
Gets around issue with reverse proxy adding localhost address
Browse files Browse the repository at this point in the history
  • Loading branch information
myleshorton committed Sep 14, 2015
1 parent 0516bc5 commit c9ee002
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
4 changes: 0 additions & 4 deletions src/github.com/getlantern/balancer/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ type dialer struct {
errCh chan time.Time
}

func (d *Dialer) Director(req *http.Request) {
req.Header.Set("X-LANTERN-AUTH-TOKEN", d.AuthToken)
}

func (d *dialer) start() {
d.active = 1
// to avoid blocking sender, make it buffered
Expand Down
57 changes: 42 additions & 15 deletions src/github.com/getlantern/flashlight/client/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,38 @@ import (
"runtime"
"time"

"github.com/getlantern/balancer"
"github.com/getlantern/detour"
"github.com/getlantern/flashlight/proxy"
"github.com/getlantern/flashlight/status"
)

// authTransport allows us to override request headers for authentication and for
// stripping X-Forwarded-For
type authTransport struct {
http.Transport
balancedDialer *balancer.Dialer
}

// We need to set the authentication token for the server we're connecting to,
// and we also need to strip out X-Forwarded-For that reverseproxy adds because
// it confuses the upstream servers with the additional 127.0.0.1 field when
// upstream servers are trying to determin the client IP.
func (at *authTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
norm := new(http.Request)
*norm = *req // includes shallow copies of maps, but okay
norm.Header.Del("X-Forwarded-For")
norm.Header.Set("X-LANTERN-AUTH-TOKEN", at.balancedDialer.AuthToken)
return at.Transport.RoundTrip(norm)
}

// newReverseProxy creates a reverse proxy that attempts to exit with any of
// the dialers provided by the balancer.
func (client *Client) newReverseProxy() (*httputil.ReverseProxy, error) {
transport := &http.Transport{
// We disable keepalives because some servers pretend to support
// keep-alives but close their connections immediately, which
// causes an error inside ReverseProxy. This is not an issue
// for HTTPS because the browser is responsible for handling
// the problem, which browsers like Chrome and Firefox already
// know to do.
//
// See https://code.google.com/p/go/issues/detail?id=4677
DisableKeepAlives: true,
}

// Just choose a random dialer that also takes care of things like the
// authentication token.
dialer, conn, err := client.getBalancer().TrustedDialerAndConn()

if err != nil {
log.Errorf("Could not get balanced dialer", err)
return nil, err
Expand All @@ -42,19 +50,38 @@ func (client *Client) newReverseProxy() (*httputil.ReverseProxy, error) {
return conn, err
}

innerTransport := http.Transport{
// We disable keepalives because some servers pretend to support
// keep-alives but close their connections immediately, which
// causes an error inside ReverseProxy. This is not an issue
// for HTTPS because the browser is responsible for handling
// the problem, which browsers like Chrome and Firefox already
// know to do.
//
// See https://code.google.com/p/go/issues/detail?id=4677
DisableKeepAlives: true,
TLSHandshakeTimeout: 40 * time.Second,
}
// TODO: would be good to make this sensitive to QOS, which
// right now is only respected for HTTPS connections. The
// challenge is that ReverseProxy reuses connections for
// different requests, so we might have to configure different
// ReverseProxies for different QOS's or something like that.
if runtime.GOOS == "android" || client.ProxyAll {
transport.Dial = dial
innerTransport.Dial = dial
} else {
transport.Dial = detour.Dialer(dial)
innerTransport.Dial = detour.Dialer(dial)
}

transport := &authTransport{
Transport: innerTransport,
balancedDialer: dialer,
}

rp := &httputil.ReverseProxy{
Director: dialer.Director,
Director: func(req *http.Request) {
// do nothing
},
Transport: &errorRewritingRoundTripper{
withDumpHeaders(false, transport),
},
Expand Down

0 comments on commit c9ee002

Please sign in to comment.