http.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package requests
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "github.com/go-fed/activity/streams"
  9. "github.com/go-fed/activity/streams/vocab"
  10. "github.com/owncast/owncast/services/apfederation/crypto"
  11. "github.com/owncast/owncast/services/config"
  12. log "github.com/sirupsen/logrus"
  13. )
  14. // WriteStreamResponse will write a ActivityPub object to the provided ResponseWriter and sign with the provided key.
  15. func (r *Requests) WriteStreamResponse(item vocab.Type, w http.ResponseWriter, publicKey crypto.PublicKey) error {
  16. var jsonmap map[string]interface{}
  17. jsonmap, _ = streams.Serialize(item)
  18. b, err := json.Marshal(jsonmap)
  19. if err != nil {
  20. return err
  21. }
  22. return r.WriteResponse(b, w, publicKey)
  23. }
  24. // WritePayloadResponse will write any arbitrary object to the provided ResponseWriter and sign with the provided key.
  25. func (r *Requests) WritePayloadResponse(payload interface{}, w http.ResponseWriter, publicKey crypto.PublicKey) error {
  26. b, err := json.Marshal(payload)
  27. if err != nil {
  28. return err
  29. }
  30. return r.WriteResponse(b, w, publicKey)
  31. }
  32. // WriteResponse will write any arbitrary payload to the provided ResponseWriter and sign with the provided key.
  33. func (r *Requests) WriteResponse(payload []byte, w http.ResponseWriter, publicKey crypto.PublicKey) error {
  34. w.Header().Set("Content-Type", "application/activity+json")
  35. if err := crypto.SignResponse(w, payload, publicKey); err != nil {
  36. w.WriteHeader(http.StatusInternalServerError)
  37. log.Errorln("unable to sign response", err)
  38. return err
  39. }
  40. if _, err := w.Write(payload); err != nil {
  41. w.WriteHeader(http.StatusInternalServerError)
  42. return err
  43. }
  44. return nil
  45. }
  46. // CreateSignedRequest will create a signed POST request of a payload to the provided destination.
  47. func (r *Requests) CreateSignedRequest(payload []byte, url *url.URL, fromActorIRI *url.URL) (*http.Request, error) {
  48. log.Debugln("Sending", string(payload), "to", url)
  49. req, _ := http.NewRequest(http.MethodPost, url.String(), bytes.NewBuffer(payload))
  50. c := config.Get()
  51. ua := fmt.Sprintf("%s; https://owncast.online", c.GetReleaseString())
  52. req.Header.Set("User-Agent", ua)
  53. req.Header.Set("Content-Type", "application/activity+json")
  54. if err := crypto.SignRequest(req, payload, fromActorIRI); err != nil {
  55. log.Errorln("error signing request:", err)
  56. return nil, err
  57. }
  58. return req, nil
  59. }