Check that the homeserver is reachable at startup

Closes #286.

Tested as follows (see line 4):

```
Sync v3 [0.99.10] (6fe9b18)
Debug=true LogLevel= MaxConns=0
Starting prometheus listener on :6060
13:23:33 WRN Could not contact upstream homeserver. Is SYNCV3_SERVER set correctly? error="Get \"http://localhost:8888/_matrix/client/versions\": dial tcp [::1]:8888: connect: connection refused" dest=http://localhost:8888
2023/09/26 13:23:33 OK   20230728114555_device_data_drop_id.sql (7.48ms)
2023/09/26 13:23:33 OK   20230802121023_device_data_jsonb.go (13.85ms)
2023/09/26 13:23:33 OK   20230814183302_cbor_device_data.go (9.01ms)
2023/09/26 13:23:33 OK   20230822180807_bogus_snapshot_cleanup.go (7.64ms)
2023/09/26 13:23:33 OK   20230913120537_events_missing_previous.sql (7.15ms)
2023/09/26 13:23:33 goose: successfully migrated database to version: 20230913120537
13:23:33 INF creating handler
13:23:33 INF retrieved global snapshot from database
13:23:33 INF listening on 0.0.0.0:8844
13:23:33 INF StartV2Pollers num_devices=0 num_fail_decrypt=0
13:23:33 INF StartV2Pollers finished
```
This commit is contained in:
David Robertson 2023-09-26 13:24:26 +01:00
parent 6fe9b18f8c
commit 7111ab1d9f
No known key found for this signature in database
GPG Key ID: 903ECE108A39DEDD
2 changed files with 39 additions and 0 deletions

View File

@ -20,6 +20,9 @@ var ProxyVersion = ""
var HTTP401 error = fmt.Errorf("HTTP 401")
type Client interface {
// Versions fetches and parses the list of Matrix versions that the homeserver
// advertises itself as supporting.
Versions(ctx context.Context) (version []string, err error)
// WhoAmI asks the homeserver to lookup the access token using the CSAPI /whoami
// endpoint. The response must contain a device ID (meaning that we assume the
// homeserver supports Matrix >= 1.1.)
@ -49,6 +52,34 @@ func NewHTTPClient(shortTimeout, longTimeout time.Duration, destHomeServer strin
}
}
func (v *HTTPClient) Versions(ctx context.Context) ([]string, error) {
req, err := http.NewRequestWithContext(ctx, "GET", v.DestinationServer+"/_matrix/client/versions", nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "sync-v3-proxy-"+ProxyVersion)
res, err := v.Client.Do(req)
if err != nil {
return nil, err
}
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("/versions returned HTTP %d", res.StatusCode)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var parsedRes struct {
Result []string `json:"versions"`
}
err = json.Unmarshal(body, &parsedRes)
if err != nil {
return nil, fmt.Errorf("could not parse /versions response: %w", err)
}
return parsedRes.Result, nil
}
// Return sync2.HTTP401 if this request returns 401
func (v *HTTPClient) WhoAmI(ctx context.Context, accessToken string) (string, string, error) {
req, err := http.NewRequestWithContext(ctx, "GET", v.DestinationServer+"/_matrix/client/r0/account/whoami", nil)

8
v3.go
View File

@ -1,6 +1,7 @@
package slidingsync
import (
"context"
"embed"
"encoding/json"
"fmt"
@ -86,6 +87,13 @@ func allowCORS(next http.Handler) http.HandlerFunc {
func Setup(destHomeserver, postgresURI, secret string, opts Opts) (*handler2.Handler, http.Handler) {
// Setup shared DB and HTTP client
v2Client := sync2.NewHTTPClient(opts.HTTPTimeout, opts.HTTPLongTimeout, destHomeserver)
// Sanity check that we can contact the upstream homeserver.
_, err := v2Client.Versions(context.Background())
if err != nil {
logger.Warn().Err(err).Str("dest", destHomeserver).Msg("Could not contact upstream homeserver. Is SYNCV3_SERVER set correctly?")
}
db, err := sqlx.Open("postgres", postgresURI)
if err != nil {
sentry.CaptureException(err)