syncthing/cmd/strelaysrv/pool.go

95 lines
2.1 KiB
Go
Raw Normal View History

2016-06-02 12:16:02 +00:00
// Copyright (C) 2015 Audrius Butkevicius and Contributors.
2015-09-07 08:21:23 +00:00
package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
2015-09-07 08:21:23 +00:00
"net/url"
"time"
)
const (
httpStatusEnhanceYourCalm = 429
)
func poolHandler(pool string, uri *url.URL, mapping mapping) {
2015-09-21 21:33:29 +00:00
if debug {
log.Println("Joining", pool)
}
2015-09-07 08:21:23 +00:00
for {
uriCopy := *uri
uriCopy.Host = mapping.Address().String()
2015-09-07 08:21:23 +00:00
var b bytes.Buffer
json.NewEncoder(&b).Encode(struct {
URL string `json:"url"`
}{
uriCopy.String(),
2015-09-07 08:21:23 +00:00
})
resp, err := httpClient.Post(pool, "application/json", &b)
2015-09-07 08:21:23 +00:00
if err != nil {
log.Printf("Error joining pool %v: HTTP request: %v", pool, err)
2015-09-07 08:21:23 +00:00
time.Sleep(time.Minute)
continue
}
bs, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
log.Printf("Error joining pool %v: reading response: %v", pool, err)
time.Sleep(time.Minute)
continue
}
switch resp.StatusCode {
case http.StatusOK:
2015-09-07 08:21:23 +00:00
var x struct {
EvictionIn time.Duration `json:"evictionIn"`
}
if err := json.Unmarshal(bs, &x); err == nil {
2015-09-07 08:21:23 +00:00
rejoin := x.EvictionIn - (x.EvictionIn / 5)
log.Printf("Joined pool %s, rejoining in %v", pool, rejoin)
2015-09-07 08:21:23 +00:00
time.Sleep(rejoin)
continue
} else {
log.Printf("Joined pool %s, failed to deserialize response: %v", pool, err)
2015-09-07 08:21:23 +00:00
}
case http.StatusInternalServerError:
log.Printf("Failed to join %v: server error", pool)
log.Printf("Response data: %s", bs)
time.Sleep(time.Minute)
continue
case http.StatusBadRequest:
log.Printf("Failed to join %v: request or check error", pool)
log.Printf("Response data: %s", bs)
time.Sleep(time.Minute)
continue
case httpStatusEnhanceYourCalm:
log.Printf("Failed to join %v: under load (rate limiting)", pool)
time.Sleep(time.Minute)
continue
case http.StatusUnauthorized:
log.Printf("Failed to join %v: IP address not matching external address", pool)
log.Println("Aborting")
return
default:
log.Printf("Failed to join %v: unexpected status code from server: %d", pool, resp.StatusCode)
log.Printf("Response data: %s", bs)
time.Sleep(time.Minute)
continue
2015-09-07 08:21:23 +00:00
}
2015-09-07 08:21:23 +00:00
time.Sleep(time.Hour)
}
}