Skip to content

Commit

Permalink
retry requests to get passed occasional 403 errors closes #3238
Browse files Browse the repository at this point in the history
  • Loading branch information
myleshorton committed Oct 6, 2015
1 parent cd28b0d commit 85110ea
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
19 changes: 12 additions & 7 deletions src/github.com/getlantern/flashlight/util/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,32 +95,35 @@ func (df *dualFetcher) Do(req *http.Request) (*http.Response, error) {
responses := make(chan *http.Response, 2)
errs := make(chan error, 2)

request := func(client HTTPFetcher, req *http.Request) bool {
request := func(client HTTPFetcher, req *http.Request) error {
if resp, err := client.Do(req); err != nil {
log.Errorf("Could not complete request with: %v, %v", frontedUrl, err)
errs <- err
return err
} else {
if success(resp) {
log.Debugf("Got successful HTTP call!")
responses <- resp
return true
return nil
} else {
// If the local proxy can't connect to any upstread proxies, for example,
// it will return a 502.
errs <- fmt.Errorf("Bad response code: %v", resp.StatusCode)
err := fmt.Errorf("Bad response code: %v", resp.StatusCode)
errs <- err
return err
}
}
return false
}

go func() {
client := direct.NewDirectHttpClient()
if req, err := http.NewRequest("GET", frontedUrl, nil); err != nil {
log.Errorf("Could not create request for: %v, %v", frontedUrl, err)
errs <- err
} else {
log.Debug("Sending request via DDF")
if request(client, req) {
if err := request(direct, req); err != nil {
log.Errorf("Fronted request failed: %v", err)
} else {
log.Debug("Fronted request succeeded")
}
}
Expand All @@ -131,7 +134,9 @@ func (df *dualFetcher) Do(req *http.Request) (*http.Response, error) {
errs <- err
} else {
log.Debug("Sending chained request")
if request(client, req) {
if err := request(client, req); err != nil {
log.Errorf("Chained request failed %v", err)
} else {
log.Debug("Switching to chained fronter for future requests since it succeeded")
df.cf.fetcher = &chainedFetcher{}
}
Expand Down
20 changes: 19 additions & 1 deletion src/github.com/getlantern/fronted/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (ddf *directTransport) RoundTrip(req *http.Request) (resp *http.Response, e
return ddf.Transport.RoundTrip(norm)
}

// NewHttpClient creates a new http.Client that does direct domain fronting.
// NewDirectHttpClient creates a new http.Client that does direct domain fronting.
func (d *direct) NewDirectHttpClient() *http.Client {
trans := &directTransport{}
trans.Dial = d.Dial
Expand All @@ -117,6 +117,24 @@ func (d *direct) NewDirectHttpClient() *http.Client {
}
}

// Do continually retries a given request until it succeeds because some fronting providers
// will return a 403 for some domains.
func (d *direct) Do(req *http.Request) (*http.Response, error) {
for i := 0; i < 6; i++ {
client := d.NewDirectHttpClient()
if resp, err := client.Do(req); err != nil {
log.Errorf("Could not complete request %v", err)
continue
} else if resp.StatusCode > 199 && resp.StatusCode < 400 {
return resp, err
} else {
_ = resp.Body.Close()
continue
}
}
return nil, errors.New("Could not complete request even with retries")
}

// Dial persistently dials masquerades until one succeeds.
func (d *direct) Dial(network, addr string) (net.Conn, error) {
for i := 0; i < 40; i++ {
Expand Down

0 comments on commit 85110ea

Please sign in to comment.