1
0
Fork 0
forked from Mirrors/gomuks
nyxmuks/beeper/internal.go
2023-08-23 22:55:57 -07:00

80 lines
1.8 KiB
Go

package beeper
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
"maunium.net/go/mautrix"
)
var cli = &http.Client{Timeout: 30 * time.Second}
func newRequest(token, method, path string) *http.Request {
req := &http.Request{
URL: &url.URL{
Scheme: "https",
Host: "api.beeper.com",
Path: path,
},
Method: method,
Header: http.Header{
"Authorization": {fmt.Sprintf("Bearer %s", token)},
"User-Agent": {mautrix.DefaultUserAgent},
},
}
if method == http.MethodPut || method == http.MethodPost {
req.Header.Set("Content-Type", "application/json")
}
return req
}
func encodeContent(into *http.Request, body any) error {
var buf bytes.Buffer
err := json.NewEncoder(&buf).Encode(body)
if err != nil {
return fmt.Errorf("failed to encode request: %w", err)
}
into.Body = io.NopCloser(&buf)
return nil
}
func doRequest(req *http.Request, reqData, resp any) (err error) {
if reqData != nil {
err = encodeContent(req, reqData)
if err != nil {
return
}
}
r, err := cli.Do(req)
if err != nil {
return fmt.Errorf("failed to send request: %w", err)
}
defer r.Body.Close()
if r.StatusCode < 200 || r.StatusCode >= 300 {
var body map[string]any
_ = json.NewDecoder(r.Body).Decode(&body)
if body != nil {
retryCount, ok := body["retries"].(float64)
if ok && retryCount > 0 && r.StatusCode == 403 && req.URL.Path == "/user/login/response" {
return fmt.Errorf("%w (%d retries left)", ErrInvalidLoginCode, int(retryCount))
}
errorMsg, ok := body["error"].(string)
if ok {
return fmt.Errorf("server returned error (HTTP %d): %s", r.StatusCode, errorMsg)
}
}
return fmt.Errorf("unexpected status code %d", r.StatusCode)
}
if resp != nil {
err = json.NewDecoder(r.Body).Decode(resp)
if err != nil {
return fmt.Errorf("error decoding response: %w", err)
}
}
return nil
}