Fix Send() and ProxySend() (#105)

Co-authored-by: James Mills <prologic@shortcircuit.net.au>
Reviewed-on: #105
Reviewed-by: xuu <xuu@noreply@mills.io>
pull/104/head
James Mills 6 months ago
parent 88dcb4dda8
commit 764180a658
  1. 4
      client.go
  2. 2
      go.mod
  3. 9
      internal/api.go
  4. 2
      internal/server.go
  5. BIN
      internal/web/app.wasm
  6. 50
      send.go

@ -31,8 +31,6 @@ const (
var (
ErrNoMessages = errors.New("error: no messages found")
ErrClientNotConnected = errors.New("error: client not connected")
acceptEncodings = []string{"br", "gzip", ""}
)
type addrCache map[string]*Addr
@ -368,7 +366,7 @@ func (cli *Client) SendToAddr(addr *Addr, msg string) error {
return fmt.Errorf("error encrypting message to %s: %w", addr, err)
}
if err := Send(addr.Endpoint().String(), string(b), addr.Cap()); err != nil {
if err := cli.send.Send(cli.key, addr.Endpoint().String(), string(b), addr.Cap()); err != nil {
return fmt.Errorf("error sending message to %s: %w", addr, err)
}

@ -2,7 +2,7 @@ module go.mills.io/saltyim
go 1.18
//replace git.mills.io/prologic/msgbus => ../msgbus
//replace git.mills.io/prologic/msgbus => ../../msgbus
//replace github.com/gen2brain/beeep => ../beeep

@ -91,14 +91,13 @@ func (a *API) SendEndpoint() httprouter.Handle {
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
if signer != r.Header.Get("Signature") {
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
// TODO: Do something with signer?
log.Debugf("request signed by %s", signer)
// TODO: Queue up an internal retry and return immediately on failure?
if err := saltyim.Send(req.Endpoint, req.Message, req.Capabilities); err != nil {
http.Error(w, "Bad Request", http.StatusBadRequest)
log.WithError(err).Errorf("error sending message to %s: %w", req.Endpoint, err)
http.Error(w, "Send Error", http.StatusInternalServerError)
return
}

@ -295,7 +295,7 @@ func (s *Server) initRoutes() {
Env: map[string]string{
"LookupEndpoint": strings.TrimSuffix(s.config.BaseURL, "/") + "/api/v1/lookup/",
"SendEndpoint": strings.TrimSuffix(s.config.BaseURL, "/") + "/api/v1/send/",
"SendEndpoint": strings.TrimSuffix(s.config.BaseURL, "/") + "/api/v1/send",
},
Icon: app.Icon{

BIN
internal/web/app.wasm (Stored with Git LFS)

Binary file not shown.

@ -6,38 +6,40 @@ import (
"fmt"
"net/http"
"github.com/keys-pub/keys"
"github.com/timewasted/go-accept-headers"
"go.mills.io/salty"
)
var (
_ Sender = (*DirectSend)(nil)
_ Sender = (*ProxySend)(nil)
acceptEncodings = []string{"br", "gzip", ""}
)
type Sender interface {
Send(endpoint, msg string, cap Capabilities) error
Send(key *keys.EdX25519Key, endpoint, msg string, cap Capabilities) error
}
// Send sends the encrypted message `msg` to the Endpoint `endpoint` using a
// `POST` request and returns nil on success or an error on failure.
func Send(endpoint, msg string, cap Capabilities) error {
req := SendRequest{
Endpoint: endpoint,
Message: msg,
Capabilities: cap,
}
headers := make(http.Header)
data, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("error serialing send request: %w", err)
if cap.AcceptEncoding != "" {
ae, err := accept.Negotiate(cap.AcceptEncoding, acceptEncodings...)
if err != nil {
return fmt.Errorf("error publishing message to %s: %w", endpoint, err)
}
headers.Set("Content-Encoding", ae)
}
res, err := Request(http.MethodPost, endpoint, nil, bytes.NewBuffer(data))
res, err := Request(http.MethodPost, endpoint, headers, bytes.NewBufferString(msg))
if err != nil {
return fmt.Errorf("error publishing message to %s: %w", endpoint, err)
}
defer res.Body.Close()
return nil
}
@ -45,7 +47,7 @@ func Send(endpoint, msg string, cap Capabilities) error {
type DirectSend struct{}
// Send posts a message to an endpoint directly
func (s *DirectSend) Send(endpoint, msg string, cap Capabilities) error {
func (s *DirectSend) Send(key *keys.EdX25519Key, endpoint, msg string, cap Capabilities) error {
return Send(endpoint, msg, cap)
}
@ -59,7 +61,7 @@ type ProxySend struct {
// whatever reason (usuaully due to Cross-Orogin-Resource-Sharing policies / CORS) it
// uses the Salty Broker the PWA was served from initially to perform the send by
// proxying the send request through the broker. Why? CORS sucks.
func (s *ProxySend) Send(endpoint, msg string, cap Capabilities) error {
func (s *ProxySend) Send(key *keys.EdX25519Key, endpoint, msg string, cap Capabilities) error {
err := Send(endpoint, msg, cap)
if err == nil {
return nil
@ -67,17 +69,21 @@ func (s *ProxySend) Send(endpoint, msg string, cap Capabilities) error {
// Fallback to proxying the send request through the broker...
headers := make(http.Header)
if cap.AcceptEncoding != "" {
ae, err := accept.Negotiate(cap.AcceptEncoding, acceptEncodings...)
if err != nil {
return fmt.Errorf("error publishing message to %s: %w", endpoint, err)
}
headers.Set("Content-Encoding", ae)
req := SendRequest{
Endpoint: endpoint,
Message: msg,
Capabilities: cap,
}
data, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("error serializing send request: %w", err)
}
signed, err := salty.Sign(key, data)
if err != nil {
return fmt.Errorf("error signing send request: %w", err)
}
res, err := Request(http.MethodGet, s.SendEndpoint+endpoint, nil, nil)
res, err := Request(http.MethodPost, s.SendEndpoint, nil, bytes.NewBuffer(signed))
if err != nil {
return err
}

Loading…
Cancel
Save