freebox-exporter/fbx/http_client.go

125 lines
2.6 KiB
Go
Raw Normal View History

2021-02-25 09:04:39 +01:00
package fbx
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
2021-02-25 09:04:39 +01:00
"io/ioutil"
"net/http"
"time"
"github.com/trazfr/freebox-exporter/log"
)
var (
errAuthRequired = errors.New("auth_required")
errInvalidToken = errors.New("invalid_token")
)
type FreeboxHttpClient struct {
client http.Client
ctx context.Context
decoder func(io.Reader, interface{}) error
2021-02-25 09:04:39 +01:00
}
type freeboxAPIResponse struct {
Success bool `json:"success"`
Message string `json:"msg"`
ErrorCode string `json:"error_code"`
}
type FreeboxHttpClientCallback func(*http.Request)
func NewFreeboxHttpClient() *FreeboxHttpClient {
result := &FreeboxHttpClient{
2021-02-25 09:04:39 +01:00
client: http.Client{
Transport: &http.Transport{
2021-02-27 11:15:08 +01:00
TLSClientConfig: newTLSConfig(),
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 10 * time.Minute,
2021-02-25 09:04:39 +01:00
},
Timeout: 10 * time.Second,
},
ctx: context.Background(),
2021-02-25 09:04:39 +01:00
}
return result
2021-02-25 09:04:39 +01:00
}
func (f *FreeboxHttpClient) Get(url string, out interface{}, callbacks ...FreeboxHttpClientCallback) error {
req, err := http.NewRequestWithContext(f.ctx, "GET", url, nil)
if err != nil {
return err
}
for _, cb := range callbacks {
cb(req)
}
return f.do(req, out)
}
func (f *FreeboxHttpClient) Post(url string, in interface{}, out interface{}, callbacks ...FreeboxHttpClientCallback) error {
buffer := new(bytes.Buffer)
if err := json.NewEncoder(buffer).Encode(in); err != nil {
return err
}
req, err := http.NewRequestWithContext(f.ctx, "POST", url, buffer)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
for _, cb := range callbacks {
cb(req)
}
return f.do(req, out)
}
func (f *FreeboxHttpClient) do(req *http.Request, out interface{}) error {
2021-02-27 21:36:56 +01:00
log.Debug.Println("HTTP request:", req.Method, req.URL.Path)
2021-02-25 09:04:39 +01:00
res, err := f.client.Do(req)
if err != nil {
return err
}
var body []byte
{
defer res.Body.Close()
2021-02-25 09:04:39 +01:00
body, err = ioutil.ReadAll(res.Body)
if err != nil {
return err
}
2021-02-25 09:04:39 +01:00
}
log.Debug.Println("HTTP Result:", string(body))
apiResponse := freeboxAPIResponse{}
if err := json.Unmarshal(body, &apiResponse); err != nil {
2021-02-25 09:04:39 +01:00
return err
}
if apiResponse.Success == false {
switch apiResponse.ErrorCode {
2021-02-25 09:04:39 +01:00
case errAuthRequired.Error():
return errAuthRequired
case errInvalidToken.Error():
return errInvalidToken
default:
return fmt.Errorf("%s %s error_code=%s msg=%s", req.Method, req.URL, apiResponse.ErrorCode, apiResponse.Message)
2021-02-25 09:04:39 +01:00
}
}
result := struct {
Result interface{} `json:"result"`
}{
Result: out,
}
if err := json.Unmarshal(body, &result); err != nil {
return err
}
2021-02-25 09:04:39 +01:00
return nil
}