mirror of
https://github.com/foomo/contentserver.git
synced 2025-10-16 12:25:44 +00:00
106 lines
2.7 KiB
Go
106 lines
2.7 KiB
Go
package client
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/foomo/contentserver/pkg/handler"
|
|
"github.com/foomo/contentserver/pkg/utils"
|
|
)
|
|
|
|
type (
|
|
HTTPTransport struct {
|
|
httpClient *http.Client
|
|
endpoint string
|
|
}
|
|
HTTPTransportOption func(*HTTPTransport)
|
|
)
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Constructor
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// NewHTTPTransport will create a new http transport for the given server and client.
|
|
// Caution: the provided server url is not validated!
|
|
func NewHTTPTransport(server string, opts ...HTTPTransportOption) *HTTPTransport {
|
|
inst := &HTTPTransport{
|
|
endpoint: server,
|
|
httpClient: http.DefaultClient,
|
|
}
|
|
|
|
for _, opt := range opts {
|
|
opt(inst)
|
|
}
|
|
|
|
return inst
|
|
}
|
|
|
|
// NewHTTPClient constructs a new client to talk to the contentserver.
|
|
// It returns an error if the provided url is empty or invalid.
|
|
func NewHTTPClient(url string) (c *Client, err error) {
|
|
if url == "" {
|
|
return nil, ErrEmptyServerURL
|
|
}
|
|
|
|
// validate url
|
|
if !utils.IsValidURL(url) {
|
|
return nil, ErrInvalidServerURL
|
|
}
|
|
|
|
return New(NewHTTPTransport(url)), nil
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Options
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func HTTPTransportWithHTTPClient(v *http.Client) HTTPTransportOption {
|
|
return func(o *HTTPTransport) {
|
|
o.httpClient = v
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ~ Public methods
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
func (t *HTTPTransport) Call(ctx context.Context, route handler.Route, request interface{}, response interface{}) error {
|
|
requestBytes, errMarshal := json.Marshal(request)
|
|
if errMarshal != nil {
|
|
return errMarshal
|
|
}
|
|
req, errNewRequest := http.NewRequestWithContext(
|
|
ctx,
|
|
http.MethodPost,
|
|
t.endpoint+"/"+string(route),
|
|
bytes.NewBuffer(requestBytes),
|
|
)
|
|
if errNewRequest != nil {
|
|
return errNewRequest
|
|
}
|
|
httpResponse, errDo := t.httpClient.Do(req)
|
|
if errDo != nil {
|
|
return errDo
|
|
}
|
|
defer httpResponse.Body.Close()
|
|
|
|
if httpResponse.StatusCode != http.StatusOK {
|
|
return errors.New("non 200 reply")
|
|
}
|
|
if httpResponse.Body == nil {
|
|
return errors.New("empty response body")
|
|
}
|
|
responseBytes, errRead := io.ReadAll(httpResponse.Body)
|
|
if errRead != nil {
|
|
return errRead
|
|
}
|
|
return json.Unmarshal(responseBytes, response)
|
|
}
|
|
|
|
func (t *HTTPTransport) Close() {
|
|
// nothing to do here
|
|
}
|