summaryrefslogtreecommitdiff
path: root/vendor/github.com/superseriousbusiness/activity/pub/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/superseriousbusiness/activity/pub/handlers.go')
-rw-r--r--vendor/github.com/superseriousbusiness/activity/pub/handlers.go113
1 files changed, 113 insertions, 0 deletions
diff --git a/vendor/github.com/superseriousbusiness/activity/pub/handlers.go b/vendor/github.com/superseriousbusiness/activity/pub/handlers.go
new file mode 100644
index 000000000..bc7eeb9d8
--- /dev/null
+++ b/vendor/github.com/superseriousbusiness/activity/pub/handlers.go
@@ -0,0 +1,113 @@
+package pub
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+
+ "github.com/superseriousbusiness/activity/streams"
+)
+
+var ErrNotFound = errors.New("go-fed/activity: ActivityStreams data not found")
+
+// HandlerFunc determines whether an incoming HTTP request is an ActivityStreams
+// GET request, and if so attempts to serve ActivityStreams data.
+//
+// If an error is returned, then the calling function is responsible for writing
+// to the ResponseWriter as part of error handling.
+//
+// If 'isASRequest' is false and there is no error, then the calling function
+// may continue processing the request, and the HandlerFunc will not have
+// written anything to the ResponseWriter. For example, a webpage may be served
+// instead.
+//
+// If 'isASRequest' is true and there is no error, then the HandlerFunc
+// successfully served the request and wrote to the ResponseWriter.
+//
+// Callers are responsible for authorized access to this resource.
+type HandlerFunc func(c context.Context, w http.ResponseWriter, r *http.Request) (isASRequest bool, err error)
+
+// NewActivityStreamsHandler creates a HandlerFunc to serve ActivityStreams
+// requests which are coming from other clients or servers that wish to obtain
+// an ActivityStreams representation of data.
+//
+// Strips retrieved ActivityStreams values of sensitive fields ('bto' and 'bcc')
+// before responding with them. Sets the appropriate HTTP status code for
+// Tombstone Activities as well.
+//
+// Defaults to supporting content to be retrieved by HTTPS only.
+func NewActivityStreamsHandler(db Database, clock Clock) HandlerFunc {
+ return NewActivityStreamsHandlerScheme(db, clock, "https")
+}
+
+// NewActivityStreamsHandlerScheme creates a HandlerFunc to serve
+// ActivityStreams requests which are coming from other clients or servers that
+// wish to obtain an ActivityStreams representation of data provided by the
+// specified protocol scheme.
+//
+// Strips retrieved ActivityStreams values of sensitive fields ('bto' and 'bcc')
+// before responding with them. Sets the appropriate HTTP status code for
+// Tombstone Activities as well.
+//
+// Specifying the "scheme" allows for retrieving ActivityStreams content with
+// identifiers such as HTTP, HTTPS, or other protocol schemes.
+//
+// Returns ErrNotFound when the database does not retrieve any data and no
+// errors occurred during retrieval.
+func NewActivityStreamsHandlerScheme(db Database, clock Clock, scheme string) HandlerFunc {
+ return func(c context.Context, w http.ResponseWriter, r *http.Request) (isASRequest bool, err error) {
+ // Do nothing if it is not an ActivityPub GET request
+ if !isActivityPubGet(r) {
+ return
+ }
+ isASRequest = true
+ id := requestId(r, scheme)
+ // Lock and obtain a copy of the requested ActivityStreams value
+ err = db.Lock(c, id)
+ if err != nil {
+ return
+ }
+ // WARNING: Unlock not deferred
+ t, err := db.Get(c, id)
+ if err != nil {
+ db.Unlock(c, id)
+ return
+ }
+ db.Unlock(c, id)
+ // Unlock must have been called by this point and in every
+ // branch above
+ if t == nil {
+ err = ErrNotFound
+ return
+ }
+ // Remove sensitive fields.
+ clearSensitiveFields(t)
+ // Serialize the fetched value.
+ m, err := streams.Serialize(t)
+ if err != nil {
+ return
+ }
+ raw, err := json.Marshal(m)
+ if err != nil {
+ return
+ }
+ // Construct the response.
+ addResponseHeaders(w.Header(), clock, raw)
+ // Write the response.
+ if streams.IsOrExtendsActivityStreamsTombstone(t) {
+ w.WriteHeader(http.StatusGone)
+ } else {
+ w.WriteHeader(http.StatusOK)
+ }
+ n, err := w.Write(raw)
+ if err != nil {
+ return
+ } else if n != len(raw) {
+ err = fmt.Errorf("only wrote %d of %d bytes", n, len(raw))
+ return
+ }
+ return
+ }
+}