90 lines
1.8 KiB
Go

package blossom
import (
"context"
"encoding/json"
"fmt"
"io"
"strconv"
"github.com/cloudwego/base64x"
"github.com/nbd-wtf/go-nostr"
"github.com/valyala/fasthttp"
)
// httpCall makes an HTTP request to the media server
func (c *Client) httpCall(
ctx context.Context,
method string,
url string,
contentType string,
addAuthorization func() string,
body io.Reader,
contentSize int64,
result any,
) error {
_ = ctx
req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req)
req.SetRequestURI(c.mediaserver + url)
req.Header.SetMethod(method)
req.Header.SetContentType(contentType)
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp)
if addAuthorization != nil {
auth := addAuthorization()
if auth != "" {
req.Header.Add("Authorization", auth)
}
}
if body != nil {
req.SetBodyStream(body, int(contentSize))
}
err := c.httpClient.Do(req, resp)
if err != nil {
return fmt.Errorf("failed to call %s: %w\n", url, err)
}
if resp.Header.StatusCode() >= 300 {
reason := resp.Header.Peek("X-Reason")
return fmt.Errorf("%s returned an error (%d): %s", url, resp.StatusCode(), string(reason))
}
if result != nil {
return json.Unmarshal(resp.Body(), &result)
}
return nil
}
// authorizationHeader creates a Nostr-signed authorization header
func (c *Client) authorizationHeader(
ctx context.Context,
modify func(*nostr.Event),
) string {
evt := nostr.Event{
CreatedAt: nostr.Now(),
Kind: 24242,
Content: "blossom stuff",
Tags: nostr.Tags{
nostr.Tag{"expiration", strconv.FormatInt(int64(nostr.Now())+60, 10)},
},
}
if modify != nil {
modify(&evt)
}
if err := c.signer.SignEvent(ctx, &evt); err != nil {
return ""
}
jevt, _ := json.Marshal(evt)
return "Nostr " + base64x.StdEncoding.EncodeToString(jevt)
}